1. 程式人生 > >反爬與反反爬策略

反爬與反反爬策略

常見反爬蟲策略

知己知彼,百戰不殆。我們想防止爬蟲被 ban就得了解一些常見的反爬蟲措施。但要反爬蟲還得先識別爬蟲,所以首先講講如何識別爬蟲。

方法1:http日誌和流量分析,如果單位時間內某個IP訪問頻率和流量超過特定閾值就可以界定為爬蟲。 方法2:Headers引數檢測 Scrapy學習筆記(6)-反爬蟲與反反爬蟲策略 上圖是瀏覽器正常訪問站點時傳送的資料包,可以看到Request Headers裡面有一堆引數,目標站點可以檢測User-Agent或者Referer引數的值來判斷是否為爬蟲,順便提一下Referer引數也可以防盜鏈。 方法3:在網頁原始碼內放置一個對瀏覽器不可見的連結,正常使用者使用瀏覽器是看不到該連結的當然也不會去點選,如果檢測到該連結被點選,來訪IP就會被界定為爬蟲。 講完了爬蟲識別方法,下面開始講反爬蟲策略 1.臨時或永久封禁來訪ip 2.返回驗證碼 3.非同步載入(ajax) 4.爬蟲陷阱

常見反反爬蟲策略

針對反爬策略1可以使用高匿代理IP解決;針對反爬策略2,如果不是每次都彈驗證碼也可以使用高匿代理IP解決,如果感覺高匿代理不穩定或者收集起來不方便使用Tor網路(不懂Tor?動動你的手指百度吧_)也可以,如果每次都彈驗證碼那就得涉及到驗證碼識別了,簡單的驗證碼可以自己寫程式碼處理,python有不少知名的影象處理(識別)庫(如PIL/Pillow、Mahotas、Pymorph、pytesser、tesseract-ocr、openCV等)和演算法(比如大名鼎鼎的KNN[K鄰近演算法]和SVM[支援向量機]),但複雜的驗證碼例如涉及邏輯判斷和計算、字元粘連變形、前置噪音多色干擾、多語種字元混搭的大多也只能靠接入人工打碼平臺來對抗了;針對反爬策略3,由於採用非同步載入方式,網頁內容不會一次性全部展示出來,需要將滾動條滑到最底部才能繼續瀏覽下一頁內容,此時可以使用selenium+phantomjs解決,phantomjs是一個無頭無介面瀏覽器,使用selenium可以驅動它模擬瀏覽器的一切操作,但缺點也很明顯,爬取效率低;針對反爬策略4,看情況而定吧,如果是比較簡單的死迴圈陷阱,可以對爬蟲將要爬取的連結進行判斷,不重複爬取相同的頁面,scrapy的LinkExtractor設定unique引數為True即可或者直接設定爬蟲的最大迴圈次數。高階的陷阱筆者還沒遇到,暫不討論。此外增加爬取間隔和禁用cookie也能降低爬蟲被ban的概率。 實踐 上面說了那麼多,實踐才是硬道理,以突破IP84反爬策略為例,主要程式碼參考Scrapy學習筆記(5)-CrawlSpider+sqlalchemy實戰,下面只貼出需要修改部分的程式碼。

1.在settings.py同級目錄下新建檔案useragent.py

--coding:utf-8--

from scrapy import log import logging ‘’’ #避免被ban策略之一:使用useragent池。 使用注意:需在settings.py中進行相應的設定。 ‘’’ import random from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware class UserAgent(UserAgentMiddleware):

def __init__(self, user_agent=''):
    self.user_agent = user_agent

def process_request(self, request, spider):
    ua = random.choice(self.user_agent_list)
    if ua:
        #顯示當前使用的useragent
        #print "********Current UserAgent:%s************" %ua
        #記錄
        log.msg('Current UserAgent: '+ua, level=logging.DEBUG)
        request.headers.setdefault('User-Agent', ua)

#the default user_agent_list composes chrome,I E,firefox,Mozilla,opera,netscape
#for more user agent strings,you can find it in http://www.useragentstring.com/pages/useragentstring.php
user_agent_list = [\
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 "
    "(KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
    "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 "
    "(KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 "
    "(KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 "
    "(KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 "
    "(KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 "
    "(KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 "
    "(KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
    "(KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 "
    "(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 "
    "(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
   ]
import random, base64
class ProxyMiddleware(object):
   #代理IP列表
   proxyList = [ \
       '114.231.158.79:8088',
       '123.233.153.151:8118'
       ]
   def process_request(self, request, spider):
       # Set the location of the proxy
       pro_adr = random.choice(self.proxyList)
       print "USE PROXY -> " + pro_adr
       request.meta['proxy'] = "http://" + pro_adr
BOT_NAME = 'ip_proxy_pool'

SPIDER_MODULES = ['ip_proxy_pool.spiders']
NEWSPIDER_MODULE = 'ip_proxy_pool.spiders'

#Obey robots.txt rules
ROBOTSTXT_OBEY = False

ITEM_PIPELINES = {
   'ip_proxy_pool.pipelines.IpProxyPoolPipeline': 300,
}

#爬取間隔
DOWNLOAD_DELAY = 1

#禁用cookie
COOKIES_ENABLED = False


#重寫預設請求頭
DEFAULT_REQUEST_HEADERS = {
  'Accept': 'text/html, application/xhtml+xml, application/xml',
  'Accept-Language': 'zh-CN,zh;q=0.8',
  'Host':'ip84.com',
  'Referer':'http://ip84.com/',
  'X-XHR-Referer':'http://ip84.com/'
}

#啟用自定義UserAgent和代理IP
#See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
   'ip_proxy_pool.useragent.UserAgent': 1,
   'ip_proxy_pool.proxymiddlewares.ProxyMiddleware':100,
   'scrapy.downloadermiddleware.useragent.UserAgentMiddleware' : None,
}

4.開始爬取,發現已經能正常運行了。