爬取圖片可真的是一個可遇不可求的機會。
有需求就會動力。
目標:爬取某個網站上n多頁的鏈接,每個鏈接有n多張圖片,每一頁對應一個文件夾,每個文件夾包含n個鏈接所對應的文件夾。
步驟1:獲得網頁的所有鏈接,訪問所有鏈接,獲得鏈接里的圖片地址。
這一步通過上一篇文章的學習,同時寫好正則匹配,就可以簡單地完成。
步驟2:根據圖片地址下載圖片。
下載jpg格式的圖片其實很容易。
1 socket = urllib2.urlopen(url) 2 data = socket.read() 3 with open(path, "wb") as jpg: 4 jpg.write(data) 5 socket.close()
其中url為圖片地址,path為保存路徑。
完成這一步之后,簡單的批量下載圖片功能就完成了。
但是,下載的過程中有幾個問題。
1、下載速度慢。
我們打開網站的時候看到圖片的速度在網速不是太慢的情況下其實也不慢,但是用這種方法下載一張圖片要等很久,有時卻很快。
2、下著下著就卡在那里了。
它就是卡在那里了,不知道要等到什么時候報錯。
基于這兩個問題,我檢索了一些資料,其中這篇文章對這個情況有比較好的說明。
后改進如下。
1 #設定超時時間,單位為秒,放在程序開頭即可
2 timeout = 60
3 socket.setdefaulttimeout(timeout)
4
5 #下載圖片的時候
6 time.sleep(10)#先sleep,再讀取數據
7 socket = urllib2.urlopen(urllib2.Request(imgurl))
8 data = socket.read()
9 socket.close()
10 ...
其實這個改進當時在程序中的體現不是很明顯,但是后來我又加入了一個東西:多線程。
python的多線程有幾種方法可以實現,通過這篇博文可以對此有所了解。
在這里我采用繼承threading.Thread的方法實現多線程。
重載run方法。我這里是每下載一個圖片就開一個線程(好像不是太好,囧……)。
1 thread = Download() 2 thread.imgurl = imgurl 3 thread.path = path 4 thread.start()
這個多線程用上以后,整個程序簡直就像開足了馬力,開始大力地下載。沒一會功夫就下載了100多M的圖片!
其實我一開始是有顧慮一個問題的,就是為什么線程sleep的時候能夠偷偷地占用系統(tǒng)的時間?看看這篇文章的實驗。
也就是說,10條線程每個sleep10秒,結果也只是花了差不多10秒的時間。
圖片的下載速度很快,雖然中途有一些處理異常的網址,但是速度飛一般的快。(后來增加了一些異常處理)
很快,開始出現異常了,大量的圖片下載失敗。
研究了很久之后才發(fā)現,存儲空間不足……
于是,搬到一個10G空閑的分區(qū),開始下載,改善異常處理。
最終完成目標的時候大概完成了8G的下載量。不知道是不是流量太大了,今天老是斷網……
同時嘗試了視頻的下載,這個功能還有待發(fā)掘。