過年之后寫的第一篇。
最近需要研究一下爬蟲,這次的爬蟲不是簡單的requests+selenium+bs4或者是scrapy就能搞定的。因?yàn)橐鉀Q爬取多站點(diǎn)(200+)的問題,考慮到工作量的問題,所以要搭建一個(gè)可以較為容易配置的分布式爬蟲。
一、工具選擇
語言:python
考察過用java的爬蟲庫,雖然流程原理基本相同,但是相關(guān)庫,python好太多。
庫:scrapy-redis
之前寫的爬蟲無非就是requests+selenium+bs4的組合,IP池用的第三方提供的http隧道代理,驗(yàn)證碼上傳到打碼云解碼返回值。之前的Facebook用了一把scrapy,但是總感覺scrapy這個(gè)框架太重,之前那種數(shù)量級(jí)的爬蟲根本用不上。
這次的任務(wù)很復(fù)雜,主要難點(diǎn)在于爬多個(gè)站點(diǎn),到時(shí)候的任務(wù)分發(fā)管理和配置難易程度是首要考慮的東西??催^pyspyder,這個(gè)庫倒是很好配置,但是任務(wù)分發(fā)的支持就比較弱。所以最終選擇是scrapy-redis庫,就是在scrapy的基礎(chǔ)上,很方便的實(shí)現(xiàn)了利用redis做任務(wù)分發(fā)。如果中間鍵控制好,配置多種情況,對于不同站點(diǎn),就是堆工作量了。
二、流程控制
這次宜配置的框架應(yīng)該做好幾個(gè)點(diǎn),這套框架應(yīng)該就可以很流暢的運(yùn)轉(zhuǎn)起來了。
1. 下載器中間件
下載器中間件可以作為一個(gè)通用性組件
登錄
登錄如果是賬號(hào)密碼是較為好處理的,再麻煩一點(diǎn)是二維碼登錄,這個(gè)可以把二維碼保存下來掃描就行,更麻煩一點(diǎn)是郵箱驗(yàn)證,這個(gè)就需要監(jiān)測郵箱的收件,目前見過最復(fù)雜的是圖片點(diǎn)擊和移動(dòng)驗(yàn)證,基本無解(移動(dòng)驗(yàn)證據(jù)說有有已經(jīng)破解了)。
IP池
IP代理可以考慮兩種,錢多自己在云服務(wù)器上買幾十個(gè)上百個(gè)實(shí)例,自己搭建一個(gè)IP池,優(yōu)點(diǎn)是穩(wěn)定,我剛才看了一下AWS如果啟100個(gè)實(shí)例需要多少錢,不得不感慨,云服務(wù)商真的是太賺錢太賺錢了。如果沒有錢,有專門做這個(gè)生意的IP供應(yīng)商。但是,花出去的錢一定和IP的穩(wěn)定性成正比。
JS模擬動(dòng)作
比如說滑動(dòng)個(gè)窗口什么的
cookies切換
大部分網(wǎng)站都是一個(gè)cookies走到底,但是有些網(wǎng)站cookies是變化的,這個(gè)需要隨時(shí)監(jiān)測。
UA池
可能是以上幾點(diǎn)中難度最小的了。
2.爬蟲中間件
如果爬蟲放在服務(wù)器上,selenium用武之地不大,主要考慮抓包解析json。如果是動(dòng)態(tài)頁面,就需要上scrapy-splash,利用splash渲染頁面再返回結(jié)果。
需要說明的是,動(dòng)態(tài)頁面可以歸為一類,靜態(tài)頁面歸為一類,這部分可配置的部分只有這個(gè),所以主要工作量在于爬蟲中間件。在搭建框架過程中需要好好設(shè)計(jì)。
3.數(shù)據(jù)解析與保存
scrapy的Item通過itempipeline直接存進(jìn)數(shù)據(jù)庫。這里有一個(gè)問題,需要記錄最近一次爬蟲爬取數(shù)據(jù)的日期,這樣后期可以減少輪詢。對于數(shù)據(jù)庫的選擇首選mongodb。這個(gè)組件也是公用的。
4.任務(wù)調(diào)度
主角redis登場。先說為什么會(huì)用它。
但是如果在面對一些比較大型的站點(diǎn)的時(shí)候,單個(gè)scrapy就顯得力不從心了。要是我們能夠多個(gè)Scrapy一起采集該多好啊 人多力量大。
很遺憾Scrapy官方并不支持多個(gè)同時(shí)采集一個(gè)站點(diǎn),雖然官方給出一個(gè)方法:
將一個(gè)站點(diǎn)的分割成幾部分,交給不同的scrapy去采集。
實(shí)在是蠢的一逼。因?yàn)椴煌瑂crapy進(jìn)程之間數(shù)據(jù)不會(huì)共享,一個(gè)網(wǎng)頁并不知道哪些爬了哪些沒爬。解決方案是將幾個(gè)scrapy的任務(wù)調(diào)度放在一個(gè)redis中,利用redis進(jìn)行去重。(其實(shí)就是這么簡單,我也不知道scrapy為什么不支持。)
總結(jié)一下:
- Scrapy-Reids 就是將Scrapy原本在內(nèi)存中處理的 調(diào)度(就是一個(gè)隊(duì)列Queue)、去重、這兩個(gè)操作通過Redis來實(shí)現(xiàn)
- 多個(gè)Scrapy在采集同一個(gè)站點(diǎn)時(shí)會(huì)使用相同的redis key(可以理解為隊(duì)列)添加Request 獲取Request 去重Request,這樣所有的spider不會(huì)進(jìn)行重復(fù)采集。效率自然就嗖嗖的上去了。
- Redis是原子性的,好處不言而喻(一個(gè)Request要么被處理 要么沒被處理,不存在第三可能)
另外,scrapy-redis還有集群版。這個(gè)后期需要好好研究一下。
爬蟲框架部分就到這里,其實(shí)里面的坑還是不少,需要潛心去研究。能做好爬蟲(大型)也是不用愁工作的,以后更新一下爬蟲實(shí)踐部分。