前言
根據(jù)scrapy官方文檔:http://doc.scrapy.org/en/master/topics/practices.html#avoiding-getting-banned里面的描述,要防止scrapy被ban晌该,主要有以下幾個策略咒林。
動態(tài)設(shè)置user agent
禁用cookies
設(shè)置延遲下載
使用Google cache
使用IP地址池(Tor project臣嚣、VPN和代理IP)
使用Crawlera
由于Google cache受國內(nèi)網(wǎng)絡(luò)的影響亭病,不考慮使用冀泻;Crawlera的分布式下載住涉,我們可以在下次用一篇專門的文章進(jìn)行講解战惊。所以本文主要從動態(tài)隨機(jī)設(shè)置user agent、禁用cookies但两、設(shè)置延遲下載和使用代理IP這幾個方式鬓梅。
創(chuàng)建中間件(middlewares.py)
類RandomUserAgent主要用來動態(tài)獲取user-agent,user-agent列表USER_AGENTS在settings.py中進(jìn)行配置谨湘。
類ProxyMiddleware用來切換代理绽快,proxy列表PROXIES也是在settings.py中進(jìn)行配置芥丧。
12345678910111213141516171819202122232425262728293031323334
import randomimport base64from settings import PROXIESclass RandomUserAgent(object): """Randomly rotate user agents based on a list of predefined ones""" def init(self, agents): self.agents = agents @classmethod def from_crawler(cls, crawler): return cls(crawler.settings.getlist('USER_AGENTS')) def process_request(self, request, spider): # print "**************************" + random.choice(self.agents) request.headers.setdefault('User-Agent', random.choice(self.agents))class ProxyMiddleware(object): def process_request(self, request, spider): proxy = random.choice(PROXIES) if proxy['user_pass'] is not None: request.meta['proxy'] = "http://%s" % proxy['ip_port'] encoded_user_pass = base64.encodestring(proxy['user_pass']) request.headers['Proxy-Authorization'] = 'Basic ' + encoded_user_pass print "**************ProxyMiddleware have pass************" + proxy['ip_port'] else: print "**************ProxyMiddleware no pass************" + proxy['ip_port'] request.meta['proxy'] = "http://%s" % proxy['ip_port']
常見 User-Agent 配置
在settings.py
中設(shè)置
123456789101112131415161718
USER_AGENTS = [ "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)", "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)", "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)", "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)", "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0", "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20", "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",]
代理設(shè)置 PROXIES
在settings.py
中設(shè)置
12345678
PROXIES = [ {'ip_port': '111.11.228.75:80', 'user_pass': ''}, {'ip_port': '120.198.243.22:80', 'user_pass': ''}, {'ip_port': '111.8.60.9:8123', 'user_pass': ''}, {'ip_port': '101.71.27.120:80', 'user_pass': ''}, {'ip_port': '122.96.59.104:80', 'user_pass': ''}, {'ip_port': '122.224.249.122:8088', 'user_pass': ''},]
常見的代理網(wǎng)站http://www.xicidaili.com/
其他設(shè)置
禁用cookies
1
COOKIES_ENABLED=False
DOWNLOAD_DELAY=3
設(shè)置下載中間件
DOWNLOADER_MIDDLEWARES
1234567
DOWNLOADER_MIDDLEWARES = {# 'myproject.middlewares.MyCustomDownloaderMiddleware': 543, 'myproject.middlewares.RandomUserAgent': 1, 'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 110,# 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110, 'myproject.middlewares.ProxyMiddleware': 100,}
觀察別人的反爬措施
https://github.com/grissomsh/antiwebcrawler/blob/master/antwebcrawler.md
異常訪問行為分析
異常行為就比較多了:
user_agent不是App或者瀏覽器。例如使用了Scrapy或者HttpClient坊罢,這個比較初級续担,一般都會修改User Agent。
短時間內(nèi)大量訪問活孩。人的訪問節(jié)奏一秒中能夠點擊5次就不得了了(游戲高手能有300到400的點擊率就是曠世高手了)物遇。
順序訪問相關(guān)信息。比如順序訪問理財產(chǎn)品的信息憾儒,包括投資人询兴,還款計劃等;因為程序一般使用循環(huán)起趾,而人會跳躍诗舰。
定時訪問。定時有可能是每日阳掐,也可能是每小時始衅,因為爬蟲是定時任務(wù)冷蚂,因此比較有規(guī)律缭保。
我們在反爬蟲的過程中,發(fā)現(xiàn)了一個很有意思的方式(歡迎打賞)蝙茶,屢試不爽:
過去若干時間內(nèi)獨立用戶按照訪問請求數(shù)(count)進(jìn)行排序艺骂;
排序的方法是該用戶訪問不同url的次數(shù)(URL unique count);
如果某個獨立用戶的訪問請求數(shù)是它前面或者后面獨立用戶訪問請求數(shù)的若干分之一或者幾倍(閾值需要根據(jù)自己網(wǎng)站定義)隆夯,那么該獨立用戶就很有可能是爬蟲钳恕。
這里就主要利用了異常行為的第三點(遍歷大量URL,而一般用戶只會訪問少數(shù)鏈接)進(jìn)行蹄衷,用ELK能夠很容易實現(xiàn)忧额。
以上的異常行為更多是統(tǒng)計分析,還有一些可以通過數(shù)據(jù)挖掘的方式進(jìn)行分析愧口。例如找一些用戶使用我們的網(wǎng)站或者App睦番,得到用戶訪問的日志,這樣我們就能夠構(gòu)建用戶訪問URL的關(guān)聯(lián)規(guī)則或者圖(因為網(wǎng)頁也好耍属,應(yīng)用也好托嚣,用戶總是在打開保護(hù)B頁面鏈接的A頁面后才能訪問B頁面,因此存在關(guān)聯(lián)關(guān)系)厚骗。
當(dāng)然還有其他很多數(shù)據(jù)挖掘的方法示启,有待進(jìn)一步挖掘。
常見IP池服務(wù)
http://www.xicidaili.com/http://www.haoip.cc/http://www.haoservice.com/
polipo 和 tor
參考源碼
https://github.com/jackgitgz/CnblogsSpider
參考資料
[1] 如何讓你的scrapy爬蟲不再被ban[2] 為何大量網(wǎng)站不能抓取?爬蟲突破封禁的6種常見方法[3] 互聯(lián)網(wǎng)網(wǎng)站的反爬蟲策略淺析[4] 用 Python 爬蟲抓站的一些技巧總結(jié)[5] 如何識別PhantomJs爬蟲[6] 麻袋理財之反爬蟲實踐
[3] 中間件
轉(zhuǎn)自這里