第一階段為初步階段粉铐,只是為了了解或是花很少的時候解決當時的問題,想要完美是非常困難的卤档,一步一步來吧
第二階段為進階階段
第一階段的問題做了些總結(jié)
- 斷電后程序怎么繼續(xù)執(zhí)行
- 爬取一個頁面大概要10秒左右蝙泼,慢
針對這些問題做了些方案
- 每爬一個頁面保存一個狀態(tài),知道那些讀取完劝枣,那些沒有
- 采取多線程加快進度
做一步學習一步汤踏,現(xiàn)在在網(wǎng)站上看到
Scrapy的強大,決定試試舔腾。
首先分析需求溪胶,現(xiàn)在只需要這四個板塊的下載地址
這是最基礎的爬頁面的scrapy框架,response.body就是取得返回html代碼
下面看看我們需要爬取的數(shù)據(jù)
這里有個小技巧稳诚,直接在需要采取的數(shù)據(jù)上右鍵哗脖,然后點檢查
然后在出來的firebug的要采集的數(shù)據(jù)上右鍵,復制xPath
會看到(/html/body/div[3]/div[4]/div[4]/p[1]/b)這樣的數(shù)據(jù)采桃,多對比幾個懒熙,如果都是一樣的,就可以采取這種方式直接取得我們想要的數(shù)據(jù)普办,不在需要用正則去匹配工扎。
在這里我在chrome里面復制的第一層div是第三個,但不知道怎么找不到衔蹲,換成2才找到肢娘,難道是從0開始?但后面二個又不需要換了舆驶,真是奇了怪了橱健。可能是有一個是js后來生成的吧沙廉,暫時先解決問題拘荡,后面在來研究
這里有一個非常大的坑,就是編碼問題撬陵,新手一般都會遇到這問題珊皿,雖然就一句代碼网缝,但不搞明白的話還是要走比較多的彎路,我首先是用chardet.detect(html)查看了編碼蟋定,是gb2312的粉臊,先解碼,在轉(zhuǎn)成utf-8格式的驶兜,這樣保存為文件里面就沒問題了扼仲。
就這一句話就完成了,還是沒有經(jīng)驗啊抄淑,呵呵
在shell里面輸出這樣的是沒問題的屠凶,保存到文件就是中文的
這是采取到的數(shù)據(jù)保存的文件,中文是沒問題的
現(xiàn)在一個頁面的基礎爬取是沒問題了蝇狼,但這又遇到個問題阅畴,比如讀取下一頁連接倡怎,在爬取迅耘,在讀取下一頁,這雖然能寫出來监署,但多進程又有問題颤专,感覺scrapy的多進程不好控制。
我的想法是一個主進程钠乏,專門讀取主頁面的列表栖秕,把列表存入數(shù)據(jù)庫里面,然后開啟10個進程晓避,來根據(jù)數(shù)據(jù)庫里面數(shù)據(jù)的狀態(tài)來執(zhí)行任務
當然我這想法是在我不需要大面積爬取的情況下簇捍,如果有些需求需要大面積的爬取數(shù)據(jù),用scrapy還是很不錯的俏拱,我這里決定直接用request就行了暑塑,往scrapy這里轉(zhuǎn)了一圈,最重要的是知道了用xpath能解決非常多的匹配問題锅必∈赂瘢或許是自己對scrapy的認識深度還不夠
不過能夠解決需求就行了。
于是乎我又回到了urllib搞隐,所有說程序猿沒事還是要多學習一些庫啊驹愚,多看些文檔,這些是能改善工作效率的。
首先編碼的是list列表的讀取
這是一個讀取列表頁面的基本單元客燕,運行之后數(shù)據(jù)庫里會有這些數(shù)據(jù)
同時在開始這個進程的時候人弓,會讀取數(shù)據(jù)庫里面保存的已經(jīng)完成到那一頁的數(shù)據(jù)
每完成個循環(huán)會寫入一條到數(shù)據(jù)庫,然后倒序查找到就行劫瞳,如果查找不到就代表從第一頁開始
這算是解決了程序異常結(jié)束之后繼續(xù)執(zhí)行的問題棠耕。
然后是多進程取得下載地址了,上面四個進程是四種類型的列表讀取柠新,并下載圖片窍荧,下面是10個讀取下載地址的進程。
這是讀取下載地址的方法
首先是查看有那一條數(shù)據(jù)狀態(tài)為0的恨憎,然后更改狀態(tài)為1蕊退,開始爬取下載地址,寫入數(shù)據(jù)庫憔恳,并更改狀態(tài)為2
這里有點麻煩的是百度網(wǎng)盤地址的讀取瓤荔,每個頁面位置不一樣,開始還好钥组,后來就出問題了输硝,這里加上了re匹配,拋出異常就為空吧程梦,比較新的模板一般都有点把,以前的沒有。
這是數(shù)據(jù)庫的結(jié)構(gòu)
這是運行狀態(tài)屿附,速度還可以郎逃,內(nèi)存,cpu這塊都還好挺份,主要是網(wǎng)絡瓶頸褒翰,一張圖片大概100k左右吧。幾萬多張圖
還有寫入這塊也有點慢匀泊。畢竟是張sd卡优训。當時寫入系統(tǒng)的時候只有6M的速度
編碼過程中遇到的問題
UnicodeDecodeError: 'gb2312' codec can't decode byte 0x8a in position 19746: illegal multibyte sequence
網(wǎng)頁如果是采用的gb2312編碼的話,采集下來需要先decode('gb2312')各聘,這個問題是因為遇到了bg2312不認識的字了揣非,這里換成gbk就行了,如果更高級的換成gb18030也行伦吠。