前言
做過(guò)爬蟲(chóng)的應(yīng)該都知道,在爬取反爬比較強(qiáng)的網(wǎng)站如果同一時(shí)間獲取的數(shù)據(jù)量過(guò)大就會(huì)導(dǎo)致封IP,例如豆瓣,搜狗之類的。那么我們我們的策略就是搭建自己的代理池悠瞬,Cookie池,使得爬蟲(chóng)更像是普通用戶在操作一樣以此來(lái)解決目標(biāo)網(wǎng)站封IP的問(wèn)題涯捻。在網(wǎng)上有大量公開(kāi)的免費(fèi)代理浅妆,如果經(jīng)濟(jì)基礎(chǔ)可以的話,我們也可以購(gòu)買付費(fèi)的代理IP障癌,用過(guò)的人也應(yīng)該知道凌外,無(wú)論是免費(fèi)的還是付費(fèi)的,其實(shí)都不能保證是可用的涛浙,因?yàn)榭赡艽薎P也會(huì)被其他人用來(lái)爬取同樣的目標(biāo)站點(diǎn)而封禁趴乡,或者代理服務(wù)器突然發(fā)生故障或網(wǎng)絡(luò)繁忙。一旦我們選用了一個(gè)不可用的代理蝗拿,這勢(shì)必會(huì)影響爬蟲(chóng)的工作效率晾捏。所以我們需要提前做篩選,將不可用的代理剔除掉哀托,從而保留可用的代理惦辛。小編今天就給大家?guī)?lái)如何搭建一個(gè)高效易用的代理池。
準(zhǔn)備工作
首先需要成功安裝Redis數(shù)據(jù)庫(kù)并啟動(dòng)服務(wù)仓手,另外還需要安裝aiohttp胖齐、request、redis-py嗽冒、pyquery呀伙、Flask庫(kù),Redis安裝可以參見(jiàn)百度添坊。
代理池的目標(biāo)
我們需要做到下面的幾個(gè)目標(biāo)剿另,來(lái)實(shí)現(xiàn)易用高效的代理池
基本模塊分為4塊:存儲(chǔ)模塊,獲取模塊贬蛙,檢測(cè)模塊雨女,接口模塊。
存儲(chǔ)模塊:負(fù)責(zé)存儲(chǔ)抓取下來(lái)的代理阳准。首先要保證代理不重復(fù)氛堕,要標(biāo)識(shí)代理的可用情況,還有動(dòng)態(tài)實(shí)時(shí)處理每個(gè)代理野蝇,所以一種比較高效和方便的存儲(chǔ)方式就是使用Redis的Sorted
Set讼稚,即有序集合括儒。,存儲(chǔ)模塊同時(shí)也是4個(gè)模塊中的中心模塊和基礎(chǔ)模塊锐想,將其他模塊串聯(lián)起來(lái)帮寻。
獲取模塊:需要定時(shí)在各大代理網(wǎng)站抓取代理。代理可以是免費(fèi)公開(kāi)代理也可以是付費(fèi)代理痛倚,代理的形式都是IP加端口,此模塊盡量從不同來(lái)源獲取澜躺,盡量抓取高匿代理蝉稳,抓取成功之后將可用代理保存到數(shù)據(jù)庫(kù)中。
檢測(cè)模塊:需要定時(shí)檢測(cè)數(shù)據(jù)庫(kù)中的代理掘鄙。這里需要設(shè)置一個(gè)檢測(cè)鏈接耘戚,最好是爬取那個(gè)網(wǎng)站就檢測(cè)那個(gè)網(wǎng)站,這樣更加有針對(duì)性操漠,如果要做一個(gè)通用型的代理收津,那可以設(shè)置百度等鏈接來(lái)檢測(cè)。另外浊伙,我們需要標(biāo)識(shí)每一個(gè)代理的狀態(tài)撞秋,如設(shè)置分?jǐn)?shù)標(biāo)識(shí),10分表示可用嚣鄙,分?jǐn)?shù)越少代表越不可用吻贿。檢測(cè)一次,如果代理可用哑子,我們可以將分?jǐn)?shù)標(biāo)識(shí)立即設(shè)置為滿分10分舅列,或者在原來(lái)的基礎(chǔ)上加1分;如果代理不可用卧蜓,可以將分?jǐn)?shù)標(biāo)識(shí)減1分帐要,當(dāng)分?jǐn)?shù)減到一定閥值后,代理就直接從數(shù)據(jù)庫(kù)移除弥奸,通過(guò)這樣的標(biāo)識(shí)分?jǐn)?shù)榨惠,我們就可以辨別代理的可用情況,選用的時(shí)候會(huì)更有針對(duì)性盛霎。
接口模塊:需要用API來(lái)提供對(duì)外服務(wù)的接口冒冬。其實(shí)我們可以直接連接數(shù)據(jù)庫(kù)來(lái)取對(duì)應(yīng)的數(shù)據(jù)摩渺,但是這樣就需要知道數(shù)據(jù)庫(kù)的連接信息简烤,并且要配置連接,而比較安全和方便的方式就是提供一個(gè)Web API接口摇幻,我們通過(guò)訪問(wèn)接口即可拿到可用代理横侦。另外挥萌,由于可用代理可能有多個(gè),那么我們可以設(shè)置一個(gè)隨機(jī)返回某個(gè)可用代理的接口枉侧,這樣就能保證每個(gè)可用代理都可以取到引瀑,實(shí)現(xiàn)負(fù)載均衡。
設(shè)計(jì)思路已經(jīng)很明確了榨馁,現(xiàn)在我們就用代碼來(lái)實(shí)現(xiàn)代理池憨栽。
首先是存儲(chǔ)模塊,我們需要定義一個(gè)類來(lái)操作數(shù)據(jù)庫(kù)的有序集合翼虫,定義一些方法來(lái)實(shí)現(xiàn)分?jǐn)?shù)的設(shè)置屑柔、代理的獲取等。核心代碼如下:
其次是獲取模塊珍剑,獲取模塊的邏輯相對(duì)簡(jiǎn)單掸宛,只需要寫一個(gè)爬蟲(chóng)來(lái)從各大網(wǎng)站抓取代理就可以了。核心代碼如下:
方便起見(jiàn)招拙,我們將獲取代理的每個(gè)方法統(tǒng)一定義為crawl開(kāi)頭唧瘾,這樣擴(kuò)展的時(shí)候只需要添加crawl開(kāi)頭的方法即可。這里實(shí)現(xiàn)了幾個(gè)示例别凤,爬取的大都是網(wǎng)上的免費(fèi)網(wǎng)站饰序,還有小白購(gòu)買的付費(fèi)代理(現(xiàn)在已經(jīng)不能用了),如果你有自己的付費(fèi)代理规哪,也只需要添加到里面即可菌羽。每個(gè)代理方法都定義成了生成器,通過(guò)yeild返回一個(gè)個(gè)代理由缆。程序首先獲取網(wǎng)頁(yè)注祖,然后用解析庫(kù)進(jìn)行解析,解析出IP加端口的形式然后返回均唉。
然后定義了一個(gè)get_proxies()方法是晨,將所有的以crawl開(kāi)頭的方法調(diào)用一遍,獲取每個(gè)方法返回的代理并組合成列表形式返回舔箭。這里我們用元類來(lái)實(shí)現(xiàn)這個(gè)方法罩缴。代碼如下:
最后定義了一個(gè)Getter類,用來(lái)動(dòng)態(tài)的調(diào)用所有以crawl開(kāi)頭的方法层扶,然后獲取抓到的代理箫章,將其加入到數(shù)據(jù)庫(kù)存儲(chǔ)起來(lái):
我們已經(jīng)成功的將各個(gè)網(wǎng)站的代理獲取下來(lái)了,現(xiàn)在就需要檢測(cè)模塊來(lái)對(duì)所有代理進(jìn)行多輪檢測(cè)镜会。代理檢測(cè)可用檬寂,分?jǐn)?shù)就設(shè)置為10,不可用就丟棄或者減1戳表,這樣就可以實(shí)時(shí)改變每個(gè)代理的可用情況桶至。如要獲取有效代理只需要獲取分?jǐn)?shù)高的代理即可昼伴。由于代理的數(shù)量非常多。為了提高檢測(cè)效率镣屹,我們?cè)谶@里使用了異步請(qǐng)求庫(kù)aiohttp來(lái)進(jìn)行檢測(cè)圃郊。
為了方便的獲取代理和使代理池可以作為一個(gè)獨(dú)立服務(wù)運(yùn)行,我們?cè)黾恿艘粋€(gè)接口模塊女蜈,并以Web API的形式暴露可用代理持舆。
最后通過(guò)調(diào)度模塊調(diào)用調(diào)用以上模塊以多線程方式運(yùn)行起來(lái)。
最后我們運(yùn)行一下
再打開(kāi)瀏覽器配置的API接口 http://127.0.0.1:5555伪窖,即可看到其首頁(yè)逸寓。
再訪問(wèn)http://127.0.0.1:5555/random,即可獲取隨機(jī)可用代理惰许。
到此我們的代理池就已經(jīng)搭建成功了席覆。有了代理池史辙,爬蟲(chóng)就會(huì)方便許多汹买。另外小編建議如果搭建自己的代理池,最好是選擇付費(fèi)代理聊倔。畢竟穩(wěn)定性高一些晦毙。網(wǎng)上的免費(fèi)代理在爬取某些網(wǎng)站還是比較吃力。
讀者如果有需要ADSL代理池搭建的思路耙蔑,可以在公眾號(hào)后臺(tái)留言见妒。后續(xù)會(huì)給出Cookie池搭建的方案。
完整代碼地址獲取可在公眾號(hào)后臺(tái)回復(fù)【代理池】獲得
對(duì)爬蟲(chóng)甸陌,數(shù)據(jù)分析须揣,算法感興趣的朋友們,可以加微信公眾號(hào) TWcoding钱豁,我們一起玩轉(zhuǎn)Python耻卡。
If it works for you.Please,star.
自助者,天助之