鍍金池/ 教程/ Python/ 糗事百科的網(wǎng)絡爬蟲(v0.3)源碼及解析(簡化更新)
一個簡單的百度貼吧的小爬蟲
亮劍!爬蟲框架小抓抓 Scrapy 閃亮登場!
Opener 與 Handler 的介紹和實例應用
百度貼吧的網(wǎng)絡爬蟲(v0.4)源碼及解析
異常的處理和 HTTP 狀態(tài)碼的分類
利用 urllib2 通過指定的 URL 抓取網(wǎng)頁內(nèi)容
Python 中的正則表達式教程
爬蟲框架 Scrapy 的第一個爬蟲示例入門教程
抓取網(wǎng)頁的含義和 URL 基本構成
urllib2 的使用細節(jié)與抓站技巧
一個爬蟲的誕生全過程(以山東大學績點運算為例)
糗事百科的網(wǎng)絡爬蟲(v0.3)源碼及解析(簡化更新)

糗事百科的網(wǎng)絡爬蟲(v0.3)源碼及解析(簡化更新)

Q&A:

為什么有段時間顯示糗事百科不可用?

答:前段時間因為糗事百科添加了 Header 的檢驗,導致無法爬取,需要在代碼中模擬Header?,F(xiàn)在代碼已經(jīng)作了修改,可以正常使用。

為什么需要單獨新建個線程?

答:基本流程是這樣的:爬蟲在后臺新起一個線程,一直爬取兩頁的糗事百科,如果剩余不足兩頁,則再爬一頁。用戶按下回車只是從庫存中獲取最新的內(nèi)容,而不是上網(wǎng)獲取,所以瀏覽更順暢。也可以把加載放在主線程,不過這樣會導致爬取過程中等待時間過長的問題。

項目內(nèi)容:

用 Python 寫的糗事百科的網(wǎng)絡爬蟲。

使用方法:

新建一個 Bug.py 文件,然后將代碼復制到里面后,雙擊運行。

程序功能:

在命令提示行中瀏覽糗事百科。

原理解釋:

首先,先瀏覽一下糗事百科的主頁:http://www.qiushibaike.com/hot/page/1 可以看出來,鏈接中 page/后面的數(shù)字就是對應的頁碼,記住這一點為以后的編寫做準備。 然后,右擊查看頁面源碼:

http://wiki.jikexueyuan.com/project/python-crawler/images/9.png" alt="" />

觀察發(fā)現(xiàn),每一個段子都用 div 標記,其中 class 必為 content,title 是發(fā)帖時間,我們只需要用正則表達式將其“扣”出來就可以了。 明白了原理之后,剩下的就是正則表達式的內(nèi)容了,可以參照這篇博文: http://blog.csdn.net/wxg694175346/article/details/8929576

運行效果:

http://wiki.jikexueyuan.com/project/python-crawler/images/10.png" alt="" />

# -*- coding: utf-8 -*-    

import urllib2    
import urllib    
import re    
import thread    
import time    

#----------- 加載處理糗事百科 -----------    
class Spider_Model:    

    def __init__(self):    
        self.page = 1    
        self.pages = []    
        self.enable = False    

    # 將所有的段子都扣出來,添加到列表中并且返回列表    
    def GetPage(self,page):    
        myUrl = "http://m.qiushibaike.com/hot/page/" + page    
        user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'   
        headers = { 'User-Agent' : user_agent }   
        req = urllib2.Request(myUrl, headers = headers)   
        myResponse = urllib2.urlopen(req)  
        myPage = myResponse.read()    
        #encode的作用是將unicode編碼轉換成其他編碼的字符串    
        #decode的作用是將其他編碼的字符串轉換成unicode編碼    
        unicodePage = myPage.decode("utf-8")    

        # 找出所有class="content"的div標記    
        #re.S是任意匹配模式,也就是.可以匹配換行符    
        myItems = re.findall('<div.*?class="content".*?title="(.*?)">(.*?)</div>',unicodePage,re.S)    
        items = []    
        for item in myItems:    
            # item 中第一個是div的標題,也就是時間    
            # item 中第二個是div的內(nèi)容,也就是內(nèi)容    
            items.append([item[0].replace("\n",""),item[1].replace("\n","")])    
        return items    

    # 用于加載新的段子    
    def LoadPage(self):    
        # 如果用戶未輸入quit則一直運行    
        while self.enable:    
            # 如果pages數(shù)組中的內(nèi)容小于2個    
            if len(self.pages) < 2:    
                try:    
                    # 獲取新的頁面中的段子們    
                    myPage = self.GetPage(str(self.page))    
                    self.page += 1    
                    self.pages.append(myPage)    
                except:    
                    print '無法鏈接糗事百科!'    
            else:    
                time.sleep(1)    

    def ShowPage(self,nowPage,page):    
        for items in nowPage:    
            print u'第%d頁' % page , items[0]  , items[1]    
            myInput = raw_input()    
            if myInput == "quit":    
                self.enable = False    
                break    

    def Start(self):    
        self.enable = True    
        page = self.page    

        print u'正在加載中請稍候......'    

        # 新建一個線程在后臺加載段子并存儲    
        thread.start_new_thread(self.LoadPage,())    

        #----------- 加載處理糗事百科 -----------    
        while self.enable:    
            # 如果self的page數(shù)組中存有元素    
            if self.pages:    
                nowPage = self.pages[0]    
                del self.pages[0]    
                self.ShowPage(nowPage,page)    
                page += 1    

#----------- 程序的入口處 -----------    
print u"""  
---------------------------------------  
   程序:糗百爬蟲  
   版本:0.3  
   作者:why  
   日期:2014-06-03  
   語言:Python 2.7  
   操作:輸入quit退出閱讀糗事百科  
   功能:按下回車依次瀏覽今日的糗百熱點  
---------------------------------------  
"""  

print u'請按下回車瀏覽今日的糗百內(nèi)容:'    
raw_input(' ')    
myModel = Spider_Model()    
myModel.Start()