Python爬蟲-爬取糗事百科段子

主要功能

代碼

# -*- coding:utf-8 -*-
    import urllib
    import urllib2
    import re
    
    page = 1
    url = 'http://www.qiushibaike.com/hot/page/' + str(page)
#需要加上headers驗(yàn)證
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    headers = {'User-Agent':user_agent}
try:
    request = urllib2.Request(url,headers = headers)
    response = urllib2.urlopen(request)
#使用utf-8編碼方式
    content = response.read().decode('utf-8')
#<div class="author clearfix">.*?href.*?<img src.*?title=.*?<h2>(.*?)</h2>.*?
    pattern = re.compile('<h2>(.*?)</h2>.*?<div class="content">(.*?)</div>.*?<i class="number">(.*?)</i>(.*?)</span>',re.S)
    
#.*?代表任意無限個(gè)字符
#(.*?)代表要取得的內(nèi)容
#re.S 標(biāo)志代表在匹配時(shí)為點(diǎn)任意匹配模式,點(diǎn) . 也可以代表換行符。
    
#上面的正則翻譯過來就是-<h2>(.*?)</h2>,<div class="content">(.*?)</div>,<i class="number">(.*?)</i>(.*?)</span>
    
# print content
    
    items = re.findall(pattern,content)
    
    print items
    items = re.findall(pattern, content)
    for item in items:
        print item[0],item [1],item[2],item[3]
        
        
        except urllib2.URLError,e:
        if hasattr(e,"code"):
            print e.code
            if hasattr(e,"reason"):
                print e.reason

結(jié)果

/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 
韓冰凝 

“我在外面,麻煩你把包裹藏在門墊下面”<br/>“放心吧,我已藏好了”

1753  好笑
向陽河 

前段時(shí)間剛放暑假的兒子像剛出牢籠的小鳥,興奮不已。如今,剛剛開學(xué),兒子卻高高興興一蹦一跳地去上學(xué)。問其原因,他說:幫我媽看了一個(gè)暑假的水果攤,要多難受有多難受!

2495  好笑

擴(kuò)展

封裝成一個(gè)爬取糗事百科段子的類


# -*- coding:utf-8 -*-
import urllib
import urllib2
import re
import thread
import time

#糗事百科爬蟲類
class QSBK:

    #初始化方法,定義一些變量
    def __init__(self):
        self.pageIndex = 1
        self.user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
        #初始化headers
        self.headers = { 'User-Agent' : self.user_agent }
        #存放段子的變量,每一個(gè)元素是每一頁的段子們
        self.stories = []
        #存放程序是否繼續(xù)運(yùn)行的變量
        self.enable = False
    #傳入某一頁的索引獲得頁面代碼
    def getPage(self,pageIndex):
        try:
            url = 'http://www.qiushibaike.com/hot/page/' + str(pageIndex)
            #構(gòu)建請求的request
            request = urllib2.Request(url,headers = self.headers)
            #利用urlopen獲取頁面代碼
            response = urllib2.urlopen(request)
            #將頁面轉(zhuǎn)化為UTF-8編碼
            pageCode = response.read().decode('utf-8')
            return pageCode

        except urllib2.URLError, e:
            if hasattr(e,"reason"):
                print u"連接糗事百科失敗,錯(cuò)誤原因",e.reason
                return None

    #傳入某一頁代碼,返回本頁不帶圖片的段子列表
    def getPageItems(self,pageIndex):
        pageCode = self.getPage(pageIndex)
        if not pageCode:
            print "頁面加載失敗...."
            return None
        #名字,內(nèi)容,好笑數(shù)量,評(píng)論
        #'<div class="author clearfix">.*?href.*?<img src.*?title=.*?<h2>(.*?)</h2>.*?<div class="content">(.*?)</div>.*?<i class="number">(.*?)</i>(.*?)</a>
        pattern = re.compile('<div class="author clearfix">.*?<h2>(.*?)</h2>.*?<div class="content">(.*?)</div>.*?'+
                             '<span class="stats-vote">.*?<i class="number">(.*?)</i>.*?'+
                             '<span class="stats-comments">.*?<i class="number">(.*?)</i>',re.S)
        items = re.findall(pattern,pageCode)
        #用來存儲(chǔ)每頁的段子們
        pageStories = []
        #遍歷正則表達(dá)式匹配的信息
        for item in items:
            replaceBR = re.compile('<br/>')
            text = re.sub(replaceBR,"\n",item[1])
             #item[0]是一個(gè)段子的發(fā)布者,item[1]是內(nèi)容,item[2]是發(fā)布時(shí)間,item[4]是點(diǎn)贊數(shù)
            pageStories.append([item[0].strip(),text.strip(),item[2].strip(),item[3].strip()])
        return pageStories

    #加載并提取頁面的內(nèi)容,加入到列表中
    def loadPage(self):
        #如果當(dāng)前未看的頁數(shù)少于2頁,則加載新一頁
        if self.enable == True:
            if len(self.stories) < 2:
                #獲取新一頁
                pageStories = self.getPageItems(self.pageIndex)
                #將該頁的段子存放到全局list中
                if pageStories:
                    self.stories.append(pageStories)
                    #獲取完之后頁碼索引加一,表示下次讀取下一頁
                    self.pageIndex += 1

    #調(diào)用該方法,每次敲回車打印輸出一個(gè)段子
    def getOneStory(self,pageStories,page):
        #遍歷一頁的段子
        for story in pageStories:
            #等待用戶輸入
            input = raw_input()
            #每當(dāng)輸入回車一次,判斷一下是否要加載新頁面
            self.loadPage()
            #如果輸入Q則程序結(jié)束
            if input == "Q":
                self.enable = False
                return
            print u"第%d頁\t發(fā)布人:%s\t好笑:%s\t評(píng)論:%s\n內(nèi)容:\n%s" %(page,story[0],story[2],story[3],story[1])

    #開始方法
    def start(self):
        print u"正在讀取糗事百科,按回車查看新段子,Q退出"
        #使變量為True,程序可以正常運(yùn)行
        self.enable = True
        #先加載一頁內(nèi)容
        self.loadPage()
        #局部變量,控制當(dāng)前讀到了第幾頁
        nowPage = 0
        while self.enable:
            if len(self.stories)>0:
                #從全局list中獲取一頁的段子
                pageStories = self.stories[0]
                #當(dāng)前讀到的頁數(shù)加一
                nowPage += 1
                #將全局list中第一個(gè)元素刪除,因?yàn)橐呀?jīng)取出
                del self.stories[0]
                #輸出該頁的段子
                self.getOneStory(pageStories,nowPage)

spider = QSBK()
spider.start()

原理:

  1. 使用self.stories裝入每頁的段子數(shù)組
  2. 首先使用loadPage方法獲取第一頁的數(shù)組放入self.stories中
  3. 使用while循環(huán)獲取self.stories的第一個(gè)數(shù)組,頁數(shù)+1,并刪除self.stories的第一個(gè)數(shù)組
  4. getOneStory中有個(gè)for循環(huán)調(diào)用了input = raw_input(),只有當(dāng)self.stories中的一個(gè)數(shù)組元素遍歷完之后才繼續(xù)執(zhí)行while里面的循環(huán)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容