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