爬蟲相關問題總結

常見爬蟲框架

常見的反爬蟲措施有哪些?

1)經過 Headers 反爬蟲react

  從用戶請求的 Headers 反爬蟲是最多見的反爬蟲策略。不少網站都會對 Headers 的 User-Agent進行檢測,還有一部分網站會對 Referer 進行檢測(一些資源網站的防盜鏈就是檢測 Referer)。若是遇到了這類反爬蟲機制,能夠直接在爬蟲中添加 Headers,將瀏覽器的 User-Agent 複製到爬蟲的Headers 中;或者將 Referer 值修改成目標網站域名。對於檢測 Headers 的反爬蟲,在爬蟲中修改或者添加 Headers 就能很好的繞過。git

2)基於用戶行爲反爬蟲github

  還有一部分網站是經過檢測用戶行爲,例如同一 IP 短期內屢次訪問同一頁面,或者同一帳戶短期內屢次進行相同操做。大多數網站都是前一種狀況,對於這種狀況,使用 IP 代理就能夠解決。能夠專門寫一個爬蟲,爬取網上公開的代理 ip,檢測後所有保存起來。這樣的代理 ip 爬蟲常常會用到,最好本身準備一個。有了大量代理 ip 後能夠每請求幾回更換一個 ip,這在 requests 或者 urllib2 中很容易作到,這樣就能很容易的繞過第一種反爬蟲。對於第二種狀況,能夠在每次請求後隨機間隔幾秒再進行下一次請求。有些有邏輯漏洞的網站,能夠經過請求幾回,退出登陸,從新登陸,繼續請求來繞過同一帳號短期內不能屢次進行相同請求的限制。web

3)動態頁面的反爬蟲ajax

  上述的幾種狀況大多都是出如今靜態頁面,還有一部分網站,咱們須要爬取的數據是經過 ajax 請求獲得,或者經過 JavaScript 生成的。首先用 Firebug 或者 HttpFox 對網絡請求進行分析。若是可以找到 ajax 請求,也能分析出具體的參數和響應的具體含義,咱們就能採用上面的方法,直接利用 requests或者 urllib2 模擬 ajax 請求,對響應的 json 進行分析獲得須要的數據。可以直接模擬 ajax 請求獲取數據當然是極好的,可是有些網站把 ajax 請求的全部參數所有加密了。咱們根本沒辦法構造本身所須要的數據的請求。我這幾天爬的那個網站就是這樣,除了加密 ajax 參數,它還把一些基本的功能都封裝了,所有都是在調用本身的接口,而接口參數都是加密的。遇到這樣的網站,咱們就不能用上面的方法了,我用的是 selenium+phantomJS 框架,調用瀏覽器內核,並利用phantomJS 執行 js 來模擬人爲操做以及觸發頁面中的 js 腳本。從填寫表單到點擊按鈕再到滾動頁面,所有均可以模擬,不考慮具體的請求和響應過程,只是完完整整的把人瀏覽頁面獲取數據的過程模擬一遍。json

  用這套框架幾乎能繞過大多數的反爬蟲,由於它不是在假裝成瀏覽器來獲取數據(上述的經過添加Headers 必定程度上就是爲了假裝成瀏覽器),它自己就是瀏覽器,phantomJS 就是一個沒有界面的瀏覽器,只是操控這個瀏覽器的不是人。利用 selenium+phantomJS 能幹不少事情,例如識別點觸式(12306)或者滑動式的驗證碼,對頁面表單進行暴力破解等等。瀏覽器

ip 被封了怎麼解決,本身作過 ip 池麼?

  能夠經過 ip 代理池來解決問題, ip 代理池相關的能夠在 github 上搜索 ip proxy 本身選一個,大體思路:服務器

  1. 獲取器 經過 requests 的爬蟲爬取免費的 IP 代理網址獲取 IP。網絡

  2. 過濾器經過獲取器獲取的代理請求網頁數據有數據返回的保存進 Redis。框架

  3. 定時檢測器定時拿出一部分 Proxy 從新的用過濾器進行檢測剔除不能用的代理。

  4. 利用 Flask web 服務器提供 API 方便提取 IP

 scrapy框架如何實現大文件下載?

from twisted.web.client import Agent, getPage, ResponseDone, PotentialDataLoss
from twisted.internet import defer, reactor, protocol
from twisted.web._newclient import Response
from io import BytesIO

class _ResponseReader(protocol.Protocol):
    def __init__(self, finished, txresponse, file_name):
        self._finished = finished
        self._txresponse = txresponse
        self._bytes_received = 0
        self.f = open(file_name, mode='wb')
    def dataReceived(self, bodyBytes):
        self._bytes_received += len(bodyBytes)
        # 一點一點的下載
        self.f.write(bodyBytes)
        self.f.flush()
    def connectionLost(self, reason):
        if self._finished.called:
            return
        if reason.check(ResponseDone):
            # 下載完成
            self._finished.callback((self._txresponse, 'success'))
        elif reason.check(PotentialDataLoss):
            # 下載部分
            self._finished.callback((self._txresponse, 'partial'))
        else:
            # 下載異常
            self._finished.errback(reason)
        self.f.close()
View Code
相關文章
相關標籤/搜索