爬蟲(chóng)介紹:
用于微信公眾號(hào)以及文章的爬取,爬取速度較低網(wǎng)速測(cè)試平均為200條文章每分鐘,基本100頁(yè)的文章頁(yè)面4min之內(nèi)就可以搞定。
頁(yè)面爬取和數(shù)據(jù)抓取的速度很快,影響速度的主要是selenium的登陸操作和驗(yàn)證碼操作。另外我還設(shè)置了1~3秒的頁(yè)面下載隨機(jī)延時(shí)。

微信文章item導(dǎo)出成csv文件:

微信公眾號(hào)item導(dǎo)出成csv文件:

上圖侵刪
爬取入口:https://weixin.sogou.com/
搜狗微信提供文章搜索以及公眾號(hào)搜索
公眾號(hào)搜索url格式:https://weixin.sogou.com/weixin?query={word}&_sug_type_=&s_from=input&_sug_=n&type=2&page={page}&ie=utf8
文章搜索url格式:https://weixin.sogou.com/weixin?query={word}&_sug_type_=&s_from=input&_sug_=n&type=1&page={page}&ie=utf8
注:url中的{word} 為搜索關(guān)鍵詞,{page}為搜索的起始頁(yè)
爬取思路:scrapy + selenium
scrapy負(fù)責(zé)url的抓取,訪問(wèn)以及數(shù)據(jù)的采集,selenium負(fù)責(zé)cookie抓取以及驗(yàn)證碼的處理。
以文章的抓取為例:
下圖是page頁(yè),每頁(yè)可以獲取十條與搜索詞相關(guān)的文章:

翻頁(yè)url通過(guò)對(duì)文章url中的 {page}加1來(lái)構(gòu)造下一頁(yè)的鏈接,文章的數(shù)據(jù)的獲取通過(guò)scrapy中的response.xpath方法很容易實(shí)現(xiàn)。
登陸權(quán)限:cookies
如果按照上面的爬蟲(chóng)思路進(jìn)行,很快就會(huì)出現(xiàn)問(wèn)題。微信搜狗默認(rèn)在用戶沒(méi)有登陸的情況下,只能瀏覽前10頁(yè)。用戶需要登陸才能繼續(xù)瀏覽剩余的頁(yè)面信息。所以一開(kāi)始我們需要先登陸搜狗微信,page頁(yè)右上角有一個(gè)登陸按鈕,點(diǎn)擊掃碼登陸。獲取登陸后的cookie添加到爬蟲(chóng)中,可以繼續(xù)爬取剩余頁(yè)面

登陸操作放在scrapy的download中間件中,在middleware中創(chuàng)建一個(gè)中間件類(lèi)。設(shè)置process_request方法,如果通過(guò)中間件的reques沒(méi)有帶上cookies,則調(diào)用chrome,進(jìn)行掃碼登陸操作,保存并設(shè)置cookies。需要注意的是,Chrome中的cookies值和scrapy中的Request的Cookies值不同,所以需要先進(jìn)行格式的轉(zhuǎn)換。有時(shí)間我再寫(xiě)一篇關(guān)于requests模塊,selenium,scrapy的cookies和代理設(shè)置的文章。

重定向問(wèn)題:302
登陸后繼續(xù)爬取大概20~30頁(yè)左右,爬蟲(chóng)會(huì)返回一個(gè)狀態(tài)碼為302的response,這是微信搜狗的反爬手段之一。當(dāng)服務(wù)器檢測(cè)某個(gè)ip的請(qǐng)求速度過(guò)快時(shí),就會(huì)向ip返回302重定向,此時(shí)scrapy中的response內(nèi)容為Not Found。但是如果使用瀏覽器訪問(wèn)的,瀏覽器會(huì)跳往一個(gè)新地址:https://weixin.sogou.com/antispider/?from=%2fweixin%3Fquery%3d%E5%90%89%E4%BB%96%26_sug_type_%3d%26s_from%3dinput%26_sug_%3dn%26type%3d1%26page%3d14%26ie%3dutf8
頁(yè)面為驗(yàn)證碼頁(yè)面:

????注意到新鏈接是以https://weixin.sogou.com/antispider/開(kāi)頭的,可見(jiàn)微信對(duì)于爬蟲(chóng)還是控制得比較嚴(yán)。不過(guò)有趣的一點(diǎn)是,微信的重定向頁(yè)面也分為兩種情況。比如第一次返回重定向頁(yè)面時(shí),只要selenium設(shè)置了cookies值,打開(kāi)的頁(yè)面還是正常的page頁(yè),不會(huì)跳轉(zhuǎn)到驗(yàn)證碼頁(yè)面。這個(gè)時(shí)候更新一下cookies值還是可以繼續(xù)抓取20頁(yè)左右。當(dāng)服務(wù)器再次返回302時(shí),再用Chrome打開(kāi)就會(huì)跳轉(zhuǎn)到驗(yàn)證碼頁(yè)面了。
????一般到了這一步,scrapy基本就動(dòng)不了,所以需要使用selenium進(jìn)行打碼,打碼有兩種方式:第一種是人工打碼,即手動(dòng)輸入驗(yàn)證碼。第二種是使用打碼平臺(tái)的api,目前市場(chǎng)上的打碼平臺(tái)多種多樣,價(jià)格也差不多。如果爬取的數(shù)據(jù)量比較小,可以使用人工打碼。反之則建議打碼平臺(tái)。
selenium解決驗(yàn)證碼問(wèn)題:
? ? 當(dāng)?shù)诙N情況遇到驗(yàn)證碼頁(yè)面的時(shí)候,在scrapy的download 中間件的process_response方法中使用selenium.webdriver.Chrome打開(kāi)重定向鏈接,人工輸入驗(yàn)證碼。在通過(guò)驗(yàn)證之后,當(dāng)scrapy繼續(xù)訪問(wèn)接下來(lái)的界面的時(shí)候,還是會(huì)返回302重定向。這是因?yàn)樵谖⑿诺尿?yàn)證碼頁(yè)面驗(yàn)證通過(guò)后,服務(wù)器會(huì)修改原來(lái)的cookies值,如果scrapy繼續(xù)使用原來(lái)的cookies依然會(huì)被判定為爬蟲(chóng)。所以一旦通過(guò)了驗(yàn)證碼驗(yàn)證,就需要保存新的cookies值,并重新設(shè)置scrapy.Request的cookies。至此已經(jīng)成功的破解了微信的驗(yàn)證碼反爬功能。

后記:
????微信爬蟲(chóng)的抓取數(shù)據(jù)量相對(duì)于新浪微博而言相對(duì)比較小,所以可以使用人工打碼。一般100頁(yè)的數(shù)據(jù)抓取,最多驗(yàn)證3次。但是如果對(duì)于數(shù)據(jù)量比較大的網(wǎng)站,還是建議使用付費(fèi)的打碼平臺(tái)。如果你不想付費(fèi),也可以考慮創(chuàng)建自己的代理池,使用切換代理ip的方法進(jìn)行抓取。
? ? 實(shí)際上,如果你的ip質(zhì)量可靠,使用代理切換的方式抓取速度會(huì)比打碼的快,因?yàn)槭∪チ撕芏嗟膕elenium驅(qū)動(dòng)操作。而且代碼寫(xiě)起來(lái)相對(duì)簡(jiǎn)單些。
? ? 最后因?yàn)榈谝淮螌?xiě)博文,忘記使用markdown了,所以放上去的圖片copy不了代碼。晚點(diǎn)我把github鏈接放上來(lái)。感興趣的可以look一下。
? ? 有問(wèn)題歡迎留言或者Email
????github鏈接:微信公眾號(hào)爬蟲(chóng)
