看了下python爬蟲用法,正則匹配過濾對應字段,這裏進行最強外功:copy大法實踐html
一開始是直接從參考連接複製粘貼的,發現因爲糗百改版致使失敗,這裏對新版html分析後進行了簡單改進,把整理過程記錄以下:python
參考文章中是這樣的:正則表達式
截圖參考中的html文件佈局以下:app
分析參考中的僞代碼以下:python爬蟲
分析圖中html佈局僞代碼:ide
<div> <div class=‘author’> <a> <img></img> 「暱稱」 </a> </div> <div class=‘content’> 「內容」 </div> <div class=‘status’> <span></span> <span></span> <span></span> </div> </div>
進行匹配的正則表達式爲:佈局
'<div.*?author">.*?<a.*?<img.*?>(.*?)</a>.*?<div.*?' + 'content">(.*?)<!--(.*?)-->.*?</div>(.*?)<div class="stats.*?class="number">(.*?)</i>'
根據正則進行篩選過濾的python代碼爲:(python代碼每次執行都一致,不一樣的事正則表達式,執行代碼中的正則表達式替換爲文字,複製上下文中的進行替換便可)學習
# -*- coding: UTF-8 -*- import urllib import urllib2 import re def qiubaiWithoutImageTest(): page = 1 url = 'http://www.qiushibaike.com/hot/page/' + str(page) 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) content = response.read().decode('utf-8') # pattern = re.compile('<div.*?author">.*?<a.*?<img.*?>(.*?)</a>.*?<div.*?' + # 'content">(.*?)<!--(.*?)-->.*?</div>(.*?)<div class="stats.*?class="number">(.*?)</i>', # re.S) pattern = re.compile('正則表達式', re.S) items = re.findall(pattern, content) print items for item in items: print item[0],item[1],item[2],item[3] # haveImg = re.search("img", item[3]) # if not haveImg: # # print item # print item[0], item[1], item[2], item[4] except urllib2.URLError, e: if hasattr(e, "code"): print e.code if hasattr(e, "reason"): print e.reason #執行代碼 qiubaiWithoutImageTest()
可是,據說可是以前的話都是廢話。。。ui
可是由於糗百改版成以下圖中的格式:編碼
因此只能參考照貓畫虎按照新格式進行正則表達式的修改了:
分析新的html僞代碼格式以下:
<div> <div class=‘author’> <a><img></img></a> <a><h2>’暱稱’</h2></a> <div>年齡</div> </div> <a class=‘contentHerf’> <div class=‘content’> <span>’內容’</span> </div> </a> <div class=‘status’> <span></span> <span></span> <span></span> </div> </div>
因此新版的正則表達式修改以下:
LZ正則水平有限,進行了屢次嘗試才匹配成功。。。,把各個版本記錄以下 =======版本1(未經過) '<div.*?author">.*?<a.*?<img.*?>(.*?)</a>.*?<a.*?><h2.*?>(.*?)</h2>.*?</a>.*?<a.*?contentHerf">.*?<div.*?' + 'content」>(.*?)<span.*?>(.*?)</span>.*?<!--(.*?)-->.*?</div>(.*?)</a>.*?<div class="stats.*?class="number">(.*?)</i>' ========版本2(未經過) '<div.*?author">.*?<a.*?<img.*?>(.*?)</a>.*?<a.*?><h2.*?>(.*?)</h2>.*?</a>.*?<a.*?contentHerf">.*?<div.*?content">(.*?)<span.*?>(.*?)</span>.*?<!--(.*?)-->.*?</div>(.*?)</a>.*?<div class="stats.*?class="number">(.*?)</i>' =========版本3(未經過) '<div.*?author">.*?<a.*?<img.*?>(.*?)</a>.*?<a.*?>.*?<h2.*?>(.*?)</h2>.*?</a>.*?<a.*?contentHerf">.*?<div.*?content">(.*?)<span.*?>(.*?)</span>.*?</div>.*?</a>.*?<div class="stats.*?class="number">(.*?)</i>' =========版本4(經過僅有內容) '<div.*?content">(.*?)<span.*?>(.*?)</span>.*?</div>' =========版本5(經過:內容、暱稱) '<div.*?author clearfix">.*?<a.*?<img.*?>(.*?)</a>.*?<a.*?<h2.*?>(.*?)</h2>.*?</a>.*?</div>.*?<div.*?content">(.*?)<span.*?>(.*?)</span>.*?</div>' =========版本6(經過:內容、暱稱、年齡) '<div.*?author clearfix">.*?<a.*?<h2.*?>(.*?)</h2>.*?</a>.*?<div.*?articleGender manIcon">(.*?)</div>.*?</div>.*?<div.*?content">(.*?)<span.*?>(.*?)</span>.*?</div>'
最終終於看到了以下結果:
胖香嬌喘助理 31 老妹單身好久了,一直沒對象,那天跟我出去坐公交,身邊站着一個小夥子,小婊砸一直往人小夥子身邊蹭。<br/>忽然,這小婊砸捂着頭:「哎呦!我頭暈,不行,暈了。。。」說着,順勢倒在人家小夥子懷裏。<br/>小夥子嚇壞了,搖了搖老妹:「大姐,大姐,您沒事吧!」<br/>老妹一聽,怒不可遏:「叫誰大姐呢?我有這麼老嗎?」說着,給了人家一個白眼,還沒到站就下車了。<br/>剩我一臉矇蔽。。這招幾百年前就有人用了。 萌面大叔l 26 我對蟬說,他日再見要等來年!蟬對我說,他日重逢要等來生! 逍遙ベ假行僧 29 初聞不知曲中意,在聽已經是曲中人。 現知詞意惟落淚,不見當年陪孤人。 既然亦是曲中人,爲什麼還聽曲中曲。 曲中思念今猶在,不見當年夢中人。 逆流而上669 26 一次歷史考試,問:1966年至1999年發生了哪三件大事。一奇葩同窗是這樣回答的:「1969年,我爸出生了;1972年我媽出生了;1995年,一個晴天霹靂,神通常的人物——我誕生了!」而後這張試卷就在公告欄裏掛了一個星期! 匿名用戶 38 公司高層來咱們基層調研,到咱們單位的是位副總,筆桿子小李又開始嘚瑟着發報道,還把稿子發到咱們單位羣,其中有這幾句話「某總深刻基層調研一線生產生活狀況,與一線職工同吃同住......」我@了他一下,說:「在職工前面加個女字就更好了。」就在這時,某副總@了我一下:「到我辦公室來一下。」我擦,誰把副總拉羣裏來的?[哀怨][哀怨][哀怨] 匿名用戶 0 沒有更好的辦法了 a金釗 24 男生用「沒事,不疼。」欺騙了多少女生;女生用「啊,疼!」欺騙了多少男生。 青青子衿憂我心 24 甲:怎麼了?看着你氣色不太好<br/>乙:昨兒喝多了,也吐也瀉<br/><br/>甲:喝多少啊?成這德行<br/>乙:喝了一打老酸奶。。。<br/>聽得都TM醉了,,,, 請叫我小智 21 看懂絕逼是污神。 surepman 22 這真不是故意的 傻晴° 38 開會,女同事讓我坐她旁邊,我心裏一陣激動。我坐定後,她拿出手機玩了起來,說:你坐這領導(在側面)就看不見我了。 挖鼻孔的老虎 99 晚上回到家,老婆用手機邊拍我邊問:「不是說加班嗎,怎麼有酒味?」<br/>我面對攝像頭有點不自在:「我,我口渴,路上買了瓶啤酒喝。」<br/>老婆拿着手機搗鼓了好一下子,而後說:「我媽不信、我妹妹不信、我全體閨蜜不信,連我9歲的侄女都以爲你沒加班只是去了喝酒。」 今狐小妖 30 二樓二樓,別拿着手機看了電話不會打來的 你的選擇你的選擇 35 這一家子拖鞋真會放,整齊,還有什麼?
LZ是Python新手,水平有限,僅做爲學習參考使用!
貼上後續參考中的進階代碼
# -*- 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} # 存放段子的變量,每個元素是每一頁的段子們 self.stories = [] # 存放程序是否繼續運行的變量 self.enable = False # 傳入某一頁的索引得到頁面代碼 def getPage(self, pageIndex): try: url = 'http://www.qiushibaike.com/hot/page/' + str(pageIndex) # 構建請求的request request = urllib2.Request(url, headers=self.headers) # 利用urlopen獲取頁面代碼 response = urllib2.urlopen(request) # 將頁面轉化爲UTF-8編碼 pageCode = response.read().decode('utf-8') # print pageCode return pageCode except urllib2.URLError, e: if hasattr(e, "reason"): print u"鏈接糗事百科失敗,錯誤緣由", e.reason return None # 傳入某一頁代碼,返回本頁不帶圖片的段子列表 def getPageItems(self, pageIndex): pageCode = self.getPage(pageIndex) if not pageCode: print "頁面加載失敗...." return None pattern = re.compile('<div.*?author clearfix">.*?<a.*?<h2.*?>(.*?)</h2>.*?</a>.*?<div.*?articleGender manIcon">(.*?)</div>.*?</div>.*?<div.*?content">(.*?)<span.*?>(.*?)</span>.*?</div>', re.S) items = re.findall(pattern, pageCode) # 用來存儲每頁的段子們 pageStories = [] # 遍歷正則表達式匹配的信息 for item in items: for itemInItem in item: pageStories.append(itemInItem.strip()) print itemInItem # 是否含有圖片 # haveImg = re.search("img", item[3]) # # 若是不含有圖片,把它加入list中 # if not haveImg: # replaceBR = re.compile('<br/>') # text = re.sub(replaceBR, "\n", item[1]) # # item[0]是一個段子的發佈者,item[1]是內容,item[2]是發佈時間,item[4]是點贊數 # pageStories.append([item[0].strip(), text.strip(), item[2].strip(), item[4].strip()]) return pageStories # 加載並提取頁面的內容,加入到列表中 def loadPage(self): # 若是當前未看的頁數少於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 # 調用該方法,每次敲回車打印輸出一個段子 def getOneStory(self, pageStories, page): # 遍歷一頁的段子 for story in pageStories: # 等待用戶輸入 input = raw_input() # 每當輸入回車一次,判斷一下是否要加載新頁面 self.loadPage() # 若是輸入Q則程序結束 if input == "Q": self.enable = False return print u"第%d頁\t發佈人:%s\t發佈時間:%s\t贊:%s\n%s" % (page, story[0], story[2], story[3], story[1]) # 開始方法 def start(self): print u"正在讀取糗事百科,按回車查看新段子,Q退出" # 使變量爲True,程序能夠正常運行 self.enable = True # 先加載一頁內容 self.loadPage() # 局部變量,控制當前讀到了第幾頁 nowPage = 0 while self.enable: if len(self.stories) > 0: # 從全局list中獲取一頁的段子 pageStories = self.stories[0] # 當前讀到的頁數加一 nowPage += 1 # 將全局list中第一個元素刪除,由於已經取出 del self.stories[0] # 輸出該頁的段子 self.getOneStory(pageStories, nowPage) qbspider = QSBK() qbspider.start()#在log中敲入enter進行下一頁數據展現,目前還有一些問題
參考連接: