用Python爬取圖片網站——基於BS4+多執行緒的處理

發表於2016-04-25

我有一個朋友,喜歡在一個圖站看圖(xie)片(zhen),光看就算了,他還有收集癖,想把網站的所有圖片都下載下來,於是找我幫忙。
本業餘玩家經過【好久的】研究,終於實現,寫成本教程。本人經濟學專業,程式設計純屬玩票,不足之處請指出,勿噴,謝謝。
本文分兩部分:第一部分是基礎方法,也就是單執行緒下爬圖片的流程;第二部分是使用了多執行緒的功能,大大提高了爬取的效率。

前言

本次爬取基於的是BeautifulSoup+urllib/urllib2模組,Python另一個高效的爬蟲模組叫Scrapy,但是我至今沒研究懂,因此暫時不用。

基礎流程

說明

此次爬取,在輸入端僅需要一個初始網址(為避免彼網站找我麻煩,就以URL代替),以及檔案儲存路徑(為保護我隱私,以PATH代替),大家在閱讀程式碼時敬請注意。
從該網站下載圖片以及檔案處理有如下幾步:【我要是會畫流程圖就好了】
1.開啟網站首頁,獲得總頁數,獲得每個專輯的連結;
2.點進某專輯,獲得專輯的標題作為儲存的資料夾名,並獲得該專輯的頁數;
3.獲取每個圖片的連結
4.下載圖片,以網站上圖片的檔名儲存至本地,同時對應第2步的資料夾。

程式碼和解釋

注1:獲取頁碼的方法,因為頁碼的HTML原始碼為<a href="/albums/XiuRen-27.html">27</a>
注2:因為我發現該網站翻頁後的網址即為首頁網址後加頁碼數字
注3:專輯標題的HTML原始碼為<div class=”title”><span class=”name”>專輯標題</span></div>

注4:將專輯標題命名為資料夾名,這裡要給title字串做些處理,下問講
注5:放每個專輯自己連結的HTML原始碼為<td><a href="/photos/XiuRen-5541.html" target="_blank"></a></td>
注6、7:放圖片的HTML原始碼為<div class="pic_box"><i.m.g(為防系統認為有圖片) src=" " alt=" "></div>
通過find_all('div', class_ = 'pic_box')找到放圖的區塊,然後用find('img')找到圖片的標籤,再用get('src')的方法獲取圖片連結

通過以上的程式碼,下載所有圖片並儲存到對應的資料夾的流程就笨拙地完成了。該方法效率極低,首先是單執行緒操作,其次用了N次巢狀迴圈,因此我想到了藉助多執行緒提高效率的方式。

多執行緒方法

介紹

Python多執行緒的方法在網上有很多文章介紹,但是都好(是)像(我)很(水)復(平)雜(低),後來我發現了一個模組,寥寥幾行就實現了功能。

from multiprocessing.dummy import Pool as ThreadPool
import urllib2

url = “http://www.cnblogs.com
urls = [url] * 50
pool = ThreadPool(4)
results = pool.map(urllib2.urlopen, urls)
pool.close()
pool.join()

其中,urls是一個列表,該模組正是用map(func, list)的方法將list的元素從前到後送入至func運算。results傳出的是一個列表類

在本案例中應用

QQ圖片20160425095743

附加

由於我處的網路環境實在是太奇葩了,即使網頁打得開、視訊流暢,在用urlopen時卻各種timeout,因此我新增了以下程式碼,將最後的連結字典儲存成一個檔案。

之後直接讀取該檔案。同時為了讓程式在無數次蛋疼的timeout報錯中自己不斷重試,又進一步增加了迴圈語句。

寫到這裡,本程式就寫完了,接下來就是跑起來然後看著一個個資料夾在電腦裡冒出來,然後一個個圖片如雨後春筍般出現吧。

以上です

最後,讀者可修改我的程式碼為自己所用,文章轉載請註明出處。(雖然我知道沒人會轉的)

相關文章