玩轉貼吧

小白爬完文字爬圖片,目標百度貼吧。

其實是偶然的機會發現了這個:

當時就想,為什麼創建這個「旅行吧」呀,

從事物發展的規律來說,就是方便大伙兒各種晒圖各種秀啊!

能拿來曬的東西,敢情應該不會差到哪去(至少比一般的百度圖片要好一些吧)

好了不多胡扯回歸正題,

幾行代碼,帶足不出戶的你,走遍萬水千山

先隨便搜了個貼,好吧就是這個了

一、目標:

1、獲取帖子標題、總頁數、評論、圖片

2、圖片寫入文件並保存

3、將各種信息實現列印(測試追蹤)

4、輸入帖子號便能實現以上操作(亦適用於其它帖子)

二、步驟:

1、獲取源碼

這個簡單,用requests的get請求方式即可。這裡設置了random.randint()獲取隨機數,在一堆範圍中獲取user_agent,主要是為了偽裝防止網站認出是爬蟲而限制抓取。至於這一堆user_agents,額,網上搜的哈哈~

#usr/bin/env python n# -*- coding: utf-8 -*-ndef getSource(self,url):n user_agents=[Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0,Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0,Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ (KHTML, like Gecko) Element Browser 5.0,IBM WebExplorer /v0.94, Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en),Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0),Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14,Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25,Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36,Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld) n index=random.randint(0,9)n user_agent=user_agents[index]n headers = {User_agent: user_agent}n html=requests.get(url,headers=headers)n return html.textn

2、獲取標題、總頁數、評論

主要是匹配正則

標題的正則

pattern=re.compile(<h1.*?title.*?>(.*?)</h1>,re.S)nitems=re.search(pattern,result)n

頁數的正則

pattern=re.compile(<h1.*?title.*?>(.*?)</h1>,re.S)nitems=re.search(pattern,result)n

評論的正則

pattern=re.compile(<h1.*?title.*?>(.*?)</h1>,re.S)nitems=re.search(pattern,result)n

3、獲取晒圖

用到BeautifulSoup,首先想到find_all()搜img標籤,得到如下

龍蛇混雜呀,不僅包括各種旅行晒圖,還有鏈接中包含head的頭像圖,含emoticon的表情圖等等,寶寶內心是崩潰噠。

如何洗出我們想要的內容呢?

別著急,仔細觀察這些個鏈接,逐個點開一試就會發現,凡是屬於晒圖的,接帶有屬性class=BDE_Image

我的天,直接find_all()限定範圍,再循環打出item[src],分分鐘搞定鏈接!要有多簡單就有簡單,最後將鏈接保存至一個list中。

4、創建目錄

用到makedirs(),值得注意的是,如果想將文件夾創建至非系統默認的地方,需要用到chdir()來更改環境變數。

5、保存晒圖

萬水千山走遍,目錄也創建,接下來就是保存圖片。又用到文件操作相關知識,千萬注意,要想將圖片成功保存至上面創建的目錄,必需指定絕對路徑,所以設置self.path是全局變數,為了方便此處調用。

6、集合各操作並獲取多頁

兩個循環,一個是多頁,一個是多個圖片的保存。關鍵在格式化每一頁索引鏈接。

觀察可發現規律,網頁URL格式為:http://tieba.baidu.com/p+帖子號+?pn=+頁數

所以可以設置如下:

self.siteURL = http://tieba.baidu.com/p/ + str(Num)nself.url=self.siteURL+?pn=+str(page)n

三、代碼

以上就是基本的思路,接下來分享代碼,如有錯誤還望指正

#!/usr/bin/env python n#-*- coding: utf-8 -*- n__author__=WYYn__date__=2017.03.14nn#實戰小項目:百度貼吧爬蟲nimport urllib2nimport requestsnimport renimport osnimport timenimport randomnfrom bs4 import BeautifulSoupnn#定義一個Tool()類方便清洗數據nclass Tool():n removeImg = re.compile(<img.*?>|{7}| ) # 去除img標籤,1-7位空格, n removeAddr = re.compile(<a.*?>|</a>) # 刪除超鏈接標籤n replaceLine = re.compile(<tr>|<div>|</div>|</p>) # 把換行的標籤換位nn replaceTD = re.compile(<td>) # 把表格製表<td>換為tn replaceBR = re.compile(<br><br>|<br>|</br>|</br></br>) # 把換行符或者雙換行符換為nn removeExtraTag = re.compile(.*?) # 把其餘標籤剔除n removeNoneLine = re.compile(n+) # 把多餘空行刪除n def replace(self, x):n x = re.sub(self.removeImg, "", x)n x = re.sub(self.removeAddr, "", x)n x = re.sub(self.replaceLine, "n", x)n x = re.sub(self.replaceTD, "t", x)n x = re.sub(self.replaceBR, "n", x)n x = re.sub(self.removeExtraTag, "", x)n x = re.sub(self.removeNoneLine, "n", x)n return x.strip() # 把strip()前後多餘內容刪除nn#定義一個Spider類nclass Spider():n #初始化參數n def __init__(self):n self.tool = Tool()nn #獲取源碼n def getSource(self,url):n user_agents=[Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0,Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0,Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ (KHTML, like Gecko) Element Browser 5.0,IBM WebExplorer /v0.94, Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en),Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0),Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14,Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25,Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36,Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)]n # user_agent在一堆範圍中隨機獲取n # random.randint()獲取隨機數,防止網站認出是爬蟲而訪問受限n index=random.randint(0,9)n user_agent=user_agents[index]n headers = {User_agent: user_agent}n html=requests.get(url,headers=headers)n return html.textnn #獲取帖子標題n def getTitle(self,url):n result=self.getSource(url)n pattern=re.compile(<h1.*?title.*?>(.*?)</h1>,re.S)n items=re.search(pattern,result)n print u這篇帖子標題為:,self.tool.replace(items.group(1))nn #獲取帖子總頁數n def getPageNumber(self,url):n result=self.getSource(url)n pattern=re.compile(<ul.*?l_posts_num.*?<span class="red">(.*?)</span>,re.S)n items=re.search(pattern,result).group(1)n print u帖子共有,items,u頁n return itemsnn #獲取評論內容n def getContent(self,url):n result = self.getSource(url)n pattern=re.compile(<a data-field.*?p_author_name.*?">(.*?)</a>.*?<div id="post_content_.*?>(.*?)</div>,re.S)n items=re.findall(pattern,result)n #獲取樓層數可以直接用循環,省去正則匹配的麻煩n number = 1n for item in items:n #item[0]為樓主,item[1]為發言內容,使用n換行符打出內容更乾淨利落n #item[1]中可能有img鏈接,用自定義Tool工具清洗n print un, number, u樓, un樓主:, item[0], un內容:, self.tool.replace(item[1])n time.sleep(0.01)n number += 1nn #獲取晒圖,清洗獲得鏈接並保存入listn def getImage(self,url):n result=self.getSource(url)n soup=BeautifulSoup(result,lxml)n #此處用BeautifulSoup顯然更高效n #find_all()返回一個list,find()返回一個元素n #注意class屬性和python內置的重合,所以加_變成class_n items=soup.find_all(img,class_="BDE_Image")n images=[]n number=0n for item in items:n print u發現一張圖,鏈接為:,item[src]n images.append(item[src])n number+=1n if number>=1:n print un,u共晒圖,number,u張,厲害了我的哥!!!n else:n print u喏,沒有圖......n return imagesnn #創建目錄n def makeDir(self,path):n self.path=path.strip()n E=os.path.exists(os.path.join(F:DesktopcodeLvXing, self.path))n if not E:n #創建新目錄,若想將內容保存至別的路徑(非系統默認),需要更環境變數n #更改環境變數用os.chdir()n os.makedirs(os.path.join(F:DesktopcodeLvXing, self.path))n os.chdir(os.path.join(F:DesktopcodeLvXing, self.path))n print u正在創建名為,self.path,u的文件夾n return self.pathn else:n print u名為,self.path,u的文件夾已經存在...n return Falsenn #萬水千山走遍,接下來就是保存美圖n def saveImage(self,detailURL,name):n data=urllib2.urlopen(detailURL).read()n fileName=name+.+jpgn #保存文件,一定要用絕對路徑 `n #所以設置self.path,是為了方便後面函數無障礙調用n f=open(rF:DesktopcodeLvXing%s%s%(self.path,fileName),wb)n f.write(data)n f.close()n print u成功保存圖片,fileNamennn #集合所有的操作,並獲取多頁n def getAllPage(self,Num):n self.siteURL = http://tieba.baidu.com/p/ + str(Num)n #獲取帖子標題n self.getTitle(self.siteURL)n #獲取帖子頁數n numbers=self.getPageNumber(self.siteURL)n for page in range(1,int(numbers)+1):n #格式化索引鏈接n self.url=self.siteURL+?pn=+str(page)n print unn,u正準備獲取第,page,u頁的內容...n #獲取評論n print un,u正準備獲取評論...n self.getContent(self.url)n #每一頁創建一個文件n self.makeDir(path=page+str(page))n #獲取圖片n print un,u正準備獲取圖片...n images=self.getImage(self.url)n print un,u正準備保存圖片...n number=1n #保存圖片,先從之前的list中找鏈接n for detailURL in images:n name=page+str(page)+num+str(number)n self.saveImage(detailURL,name)n time.sleep(0.1)n number+=1nn print unn,u完成第,page,u頁nn print unn,u恭喜,圓滿成功!nn#raw_input()實現和外部交互,想看哪個貼就看哪個貼nNum=int(raw_input(老哥兒/老妹兒,輸入帖子號唄:))nspider=Spider()nspider.getAllPage(Num)n

四、結果

終於寫完代碼啦,各種參數要注意處理好。

然後可以看到如下結果:

第一頁:

最後一頁:

看看文件的變化,圖片已乖乖躺在文件夾中啦

隨便打開是這樣的

五、擴展

爬完上面這個貼,又去胡亂搜尋,發現兩有趣的貼

喜愛攝影的盆友看過來啦~

一個是:國外朋友的世界一周旅行記1,Uca姐的攝影好美(獻給所有愛旅者)

另一個:背起畫夾去旅行——且行且繪(陸續更新)

1)、前面這一個介紹了 一個日本旅行攝影師的世界一周旅行記 的故事,照片色彩明麗、利落乾淨,迎面滿是異域風情。

舉例幾個圖:

一共100頁,一頁也就四五十張圖。。。不過攝影師的圖還是相當的贊啊

2)另一個帖子更是好玩,樓主非常有才,把沿途所見所聞都一一畫下,畫風那叫一個清新雅緻,不得不獻上膝蓋。

放幾個圖感受一下:

六、總結

總結一下本文關鍵:

1、用正則匹配標題、頁數、評論,用BeautifulSoup提取圖片,自定義Tool類進行數據清洗

2、保存圖片入文件

3、實現了隨便輸入帖子號,便可列印評論與保存圖片

其實還有很多這樣的帖子,隨便輸入帖子號便玩轉貼吧,幾行代碼走遍萬水千山!

本篇就是這樣啦~

推薦閱讀:

Python 爬蟲|深入請求(二):URL
那些年我們寫過的爬蟲
從零開始寫Python爬蟲 --- 2.4 爬蟲實踐:代理的爬取和驗證

TAG:Python | 爬虫 | 自学编程 |