Python反爬研究总结
反爬蟲常見套路
-
判斷user-agent
-
校驗(yàn)referer頭
-
校驗(yàn)cookie
-
同一IP訪問次數(shù)限制
-
js/ajax動(dòng)態(tài)渲染頁(yè)面
反反爬蟲應(yīng)對(duì)策略
1、user-agent頭校驗(yàn)
每次請(qǐng)求設(shè)置隨機(jī)user-agent頭。可以引入fake_useragent模塊或從http://useragentstring.com/pages/useragentstring.php?typ=browser獲取最新請(qǐng)求頭。
通過scrapy框架實(shí)現(xiàn),download_middleware中間件,process_request方法。示例:
# 自定義User-Agent列表
request.headers['User-Agent'] = random.choice(USER_AGENTS)# fake_useragent方式實(shí)現(xiàn)
from fake_useragent import UserAgent
request.headers['User-Agent'] = str(UserAgent().random)
2、校驗(yàn)referer頭
-
設(shè)置referer為網(wǎng)站主域名
-
通過selenium爬取,selenium會(huì)自動(dòng)為每次請(qǐng)求增加referer頭
3、校驗(yàn)cookie
對(duì)方的網(wǎng)站的cookie規(guī)則無(wú)法分析/破解難度太大。可以通過selenium/splash處理對(duì)cookie的操作,建立cookie池
4、同一ip訪問次數(shù)限制
如果同一個(gè)ip在某個(gè)時(shí)間段訪問頻次過高,會(huì)被認(rèn)為是爬蟲,封掉ip。解決辦法:
1.使用代理ip
1) 批量獲取ip,構(gòu)成ip池
2) 分次請(qǐng)求代理ip接口,每次請(qǐng)求一條ip,獲取ip和過期時(shí)間
scrapy實(shí)現(xiàn)方式,download_middleware中間件,process_request方法。示例:
request.meta['proxy'] = proxy
2.設(shè)置抓取頻率
修改scrapy settings文件
# 設(shè)置下載延遲 3s
DOWNLOAD_DELAY = 3
代理平臺(tái)對(duì)比
| 指標(biāo)平臺(tái) | 芝麻代理 | 快代理 | ... |
|---|---|---|---|
| 穩(wěn)定性 | 中(測(cè)試過程中,未發(fā)現(xiàn)代理不能用的情況) | 未使用,不明確 | ... |
| 靈活性 | 高(參數(shù)配置靈活,通過url調(diào)用) | 未使用,不明確 | ... |
5、js/ajax動(dòng)態(tài)渲染頁(yè)面
此類網(wǎng)站可以通過selenium或者splash工具來(lái)進(jìn)行處理。各自優(yōu)缺點(diǎn)對(duì)比:
| 指標(biāo)工具 | selenium | splash |
|---|---|---|
| 性能 | 低(每次請(qǐng)求需頁(yè)面加載完才能進(jìn)行下一步處理) | 高(Twisted和QT,發(fā)揮webkit并發(fā)能力) |
| 效率 | 低(模擬瀏覽器,瀏覽器底層初始化一些流程) | 高(Twisted和QT,發(fā)揮webkit并發(fā)能力) |
| 運(yùn)維成本 | 低(作為scrapy一個(gè)類庫(kù)調(diào)用) | 高(需配合docker使用,開啟docker-splash服務(wù)) |
| 內(nèi)存 | 高(隨時(shí)間推移,占用內(nèi)存越高) | 待測(cè)試... |
| 靈活性 | 中 | 高(參數(shù)配置方便) |
| 使用范圍 | 瀏覽器測(cè)試自動(dòng)化工具 | 異步渲染頁(yè)面 |
綜上所述,爬取動(dòng)態(tài)頁(yè)面數(shù)據(jù),在效率以及爬取性能上,splash會(huì)有明顯優(yōu)勢(shì)。
&Question
1、如何確保100%爬取?
1、代理ip穩(wěn)定
2、建立失敗請(qǐng)求重試機(jī)制
2、代理ip被對(duì)方網(wǎng)站封掉如何處理?(重試機(jī)制?)
通過scrapy框架download_middleware中間件,process_response方法來(lái)判斷返回參數(shù)進(jìn)行處理。示例:
def process_response(self, request, response, spider):# 判斷response狀態(tài)碼 或 返回內(nèi)容為驗(yàn)證碼,則獲取新的代理ipif response.status != 200:self.logger.info('ip被拉黑')# 更新代理ipself.update_proxy()# 返回request對(duì)象 重新發(fā)起請(qǐng)求return request# 返回response到爬蟲腳本return response
也可以作為重試機(jī)制之一。
3、selenium代理設(shè)置問題及替代方案
通過資料查找以及實(shí)踐踩坑發(fā)現(xiàn)selenium對(duì)于代理ip的設(shè)置不太友好,而且如何動(dòng)態(tài)切換代理ip也是個(gè)問題(也可以實(shí)現(xiàn))。
splash設(shè)置動(dòng)態(tài)ip比較方便。示例:
-
中間件實(shí)現(xiàn)
class ProxyMiddleware(object):def process_request(self, request, spider):request.meta['splash']['args']['proxy'] = proxyServerproxy_user_pass = "USERNAME:PASSWORD"encoded_user_pass = base64.encodestring(proxy_user_pass)request.headers["Proxy-Authorization"] = 'Basic ' + encoded_user_pass
-
spider實(shí)現(xiàn)
def start_requests(self):for url in self.start_urls:yield SplashRequest(url,url=url,callback=self.parse,args={'wait': 5,'proxy': 'http://proxy_ip:proxy_port'}
4、驗(yàn)證碼問題
-
手動(dòng)認(rèn)證(效率太低... 需要人工
-
更換ip (方便
-
打碼平臺(tái) (一般的識(shí)別驗(yàn)證碼類庫(kù)不穩(wěn)定,打碼平臺(tái)一般都需要收費(fèi)
選擇哪個(gè),哪種方式更適合,需要測(cè)試以及項(xiàng)目需求才能確定。
5、如何高效抓取
-
破解對(duì)方ajax請(qǐng)求,通過ajax請(qǐng)求獲取數(shù)據(jù),不走頁(yè)面
-
mysql連接池(Twisted、adbapi)
-
Redis分布式爬蟲(Spider.Redis)
-
數(shù)據(jù)寫入redis或MongoDB,異步讀入mysql
6、Splash
這里以亞馬遜為例,爬取亞馬遜,使用Splash沒有用selenium好,使用splash總是會(huì)出現(xiàn)響應(yīng)丟失的情況,估計(jì)是響應(yīng)時(shí)間太長(zhǎng)了,后續(xù)還需要更加完善的測(cè)試。
?
預(yù)選方案
splash + 代理ip + 隨機(jī)user_agent + cookie池 + 分布式爬蟲
總結(jié)
以上是生活随笔為你收集整理的Python反爬研究总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kazoo安装和使用
- 下一篇: Thrift架构与使用方法