1. 程式人生 > >網路爬蟲突破限制的常見方法

網路爬蟲突破限制的常見方法

開發十年,就只剩下這套架構體系了! >>>   

導讀:在網際網路上爬取資料的過程中難免出現ip被封或者伺服器返回403等等,這可能是你被網站檢測為爬蟲而採取的反爬措施,本文主要總結了一些常見的情況及規避的措施。

網路爬蟲,是一種自動獲取網頁內容的程式,它存在的時間差不多和網際網路存在的時間一樣長。然而網際網路上大量的爬蟲也給網站帶來了很大的困擾,嚴重影響了網站的正常執行,甚至威脅到資料及系統的安全,於是各式各樣的反爬蟲技術應運而生。在程式設計師的互相博弈之下,兩種技術都得到了極大的發展,比如12306的驗證碼發展史,就是一場經典的反爬蟲技術發展史,以至於12306從最初特別簡單的驗證碼發展到如今令人髮指的驗證碼。

在做網路爬蟲時,經常可能會遇到資料顯示在瀏覽器上但卻抓取不出來,也許是向伺服器提交自認為已經處理得很好的表單卻被拒絕,也許是自己的賬號或者IP地址不知道什麼原因直接被網站封殺,無法繼續訪問。此時,最可能出現的情況是:對方使用了反爬蟲技術,有意不讓爬蟲抓取資訊。接下來本文就介紹一些常見的克服網站阻止自動採集的方法來突破這些限制。

1.構造合理的 HTTP 請求頭

 

 

HTTP 的請求頭是在你每次向網路伺服器傳送請求時,傳遞的一組屬性和配置資訊。HTTP 定義了十幾種古怪的請求頭型別,不過大多數都不常用。只有下面的七個欄位被大多數瀏覽器用來初始化所有網路請求。

雖然網站可能會對HTTP請求頭的每個屬性都進行檢查,但是通常真正重要的引數就是User-Agent。無論是什麼樣的爬蟲,一定要記得把User-Agent屬性設定成不容易引起懷疑的內容,比如如果你用python的urllib標準庫時,它的User-Agent可能就會是Python-urllib/3.4,這樣就很容易被禁。另外,如果你正在處理一個警覺性非常高的網站,就要注意那些經常用卻很少檢查的請求頭,比如 Accept-Language屬性,也許它正是那個網站判斷你是否是人類訪問者的關鍵。還有一部分網站會對Referer進行檢測,比如一些資源網站的防盜鏈就是檢測Referer。如果遇到了這類反爬蟲機制,可以直接在爬蟲中新增Headers,將瀏覽器的User-Agent複製到爬蟲的Headers中;或者將Referer值修改為目標網站域名。對於檢測Headers的反爬蟲,在爬蟲中修改或者新增Headers就能很好的繞過。
另外,請求頭還可能讓網站改變內容的佈局樣式。例如,用移動裝置瀏覽網站時,通常會看到一個沒有廣告、Flash以及其他干擾的簡化的網站版本。因此,把你的請求頭User-Agent改成下面這樣,也許就可以看到一個更容易採集的網站了。
User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) App leWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53

2.設定cookie

cookie其實是儲存在使用者終端的一些被加密的資料,有些網站通過cookies來識別使用者身份,如果某個訪問總是高頻率地發請求,很可能會被網站注意到,被懷疑為爬蟲,這時網站就可以通過cookie找到這個訪問的使用者而拒絕其訪問。對於這種情況可以通過禁用cookie,主動阻止伺服器寫入。禁用cookie可以防止使用cookies識別爬蟲的網站來禁掉我們。
但是採集某些網站時cookie是不可或缺的。要在一個網站上持續保持登入狀態,需要在多個頁面中儲存一個cookie。有些網站不要求在每次登入時都獲得一個新cookie,只要儲存一箇舊的已登入的 cookie 就可以訪問。

3.降低訪問頻率

為了提高爬蟲的效率,很多人在爬蟲中使用多執行緒、非同步等手段,使得爬蟲在一個小時內甚至可以訪問數十萬次頁面,給伺服器帶來了不小的壓力,因此有一些防護措施較完備的網站就可能會阻止你快速地提交表單,或者快速地與網站進行互動。即使沒有這些安全措施,用一個比普通人快很多的速度從一個網站下載大量資訊也可能讓自己被網站封殺。
遇到這種網站,如果你對爬蟲效率要求不高,可以嘗試降低爬蟲訪問速度,比如不再使用多執行緒技術,每次訪問後設置等待時間,限制每小時訪問量等。比如在python中:

import time,random#匯入包
time.sleep(random.randint(1,9))#設定時間間隔為隨機幾秒鐘

但如果你對爬蟲效率要求比較高,每次訪問都等待無法滿足要求,那麼首先需要確定網站是根據什麼條件進行限制的,再想辦法去突破限制。比如很多網站都是通過IP來限制訪問量的,那麼就可以使用代理IP,每請求幾次就換一個IP,這樣就可以避免被禁了。

4.動態頁面的反爬蟲

上述的幾種情況大多都是出現在靜態頁面,還有一部分網站,我們需要爬取的資料是通過ajax請求得到,或者通過JavaScript生成的。對於這種情況,我們首先需要對網路請求進行分析,如果能夠找到ajax請求,也能分析出具體的引數和響應的具體含義,我們就能採用上面的方法,直接模擬ajax請求,對響應的json進行分析得到需要的資料。
如果這種方法不行,或者需要處理JS,那麼則可以採用selenium+phantomJS。PhantomJS是一個無介面的WebKit瀏覽器,除了沒有介面,基本和一般的瀏覽器一樣。Selenium是一個自動化測試工具,它可以驅動瀏覽器,兩者結合,雙劍合璧,從填寫表單到點選按鈕再到滾動頁面,全部都可以模擬,不考慮具體的請求和響應過程,只是完完整整的把人瀏覽頁面獲取資料的過程模擬一遍。 用這套框架幾乎能繞過大多數的反爬蟲,因為它不是在偽裝成瀏覽器來獲取資料(上述的通過新增Headers一定程度上就是為了偽裝成瀏覽器),phantomJS本身就是一個沒有介面的瀏覽器,只是操控這個瀏覽器的不是人而是程式。利用selenium+phantomJS能幹很多事情,cookie、JavaScript、header都能自動處理,比如現在比較流行的滑動式驗證碼,就可以使用它們解決。

5.注意隱含輸入欄位值

為了反爬蟲,一些網站會在html表單中故意新增隱藏元素,這些隱含欄位可以讓欄位的值對瀏覽器可見,但是對使用者不可見,除非看網頁原始碼。如果你爬著爬著就把隱藏元素都爬出來了,那麼就很容易被網站識別出來,只要被網站發現,就有可能立馬被封賬號或者IP,所以在提交表單前一定要先看一下元素再進行爬取。
比如下面這段html程式碼:

<html><head>
    <title>A bot-proof form</title>
    <style>
    body {overflow-x: hidden;}
    .customHidden {
        position: absolute;
        right: 50000px;
    }
    </style>
    <style type="text/css"></style>
</head>
<body>
    <h2>A bot-proof form</h2>
    <a href="http://pythonscraping.com/dontgohere" style="display:none;">Go here!</a>
    <a href="http://pythonscraping.com">Click me!</a>
    <form>
        <input type="hidden" name="phone" value="valueShouldNotBeModified">
        <p><input type="text" name="email" class="customHidden" value="intentionallyBlank"></p>
        <p><input type="text" name="firstName"></p>
        <p><input type="text" name="lastName"></p>
        <p><input type="submit" value="Submit"></p>
    </form>
</body></html>

這段程式碼包含了兩個連結,但是其中一個通過css隱藏了,一旦你訪問了這個連結,可能就會中招。而在表單中,電話號碼欄位name="phone"是一個隱含的輸入欄位,郵箱地址欄位name="email"是將元素向右移動50000畫素並隱藏滾動條,這兩個對使用者而言都是不可見的。
處理這種頁面可以在訪問前先進行分析,也可以使用Selenium,通過is_displayed來判斷元素在頁面上是否可見,從而避免被封禁。

6.使用代理

網路爬蟲幾乎所有的資料都是偽造的,但是有一項卻是不能作假的,那就是IP地址。因此很多網站為了防爬蟲,制定了一系列規則去封殺IP,簡單粗暴又十分有效。如果你的IP地址被封,那麼這時就該代理上場了。所謂代理就是介於使用者與網站之間的第三者:使用者先將請求發到代理,然後代理再發到伺服器,這樣看起來就像是代理在訪問那個網站了。這時,伺服器會將這次訪問算到代理頭上。同時用多個代理的話,單個IP的訪問量就降下去了,於是就有可能逃過一劫。
python中的requests使用代理非常簡單:

import requests
proxies = {
    "http": "XXX.XX.XX.XX:XX",
}
print requests.get('http://www.ip181.com/',proxies=proxies).content

baidu.com 是一個可以檢測代理IP的網站,它可以檢測出你使用的ip是什麼,正好可以用來檢驗自己是否使用代理ip成功。
如果你有多個代理IP,那麼可以建立一個IP池,每次隨機從IP池中選擇一個進行訪問,如果訪問失敗了,則將其從池中去除即可。

以上就是一些防止爬蟲被封禁的常見情況和解決辦法。總之,反爬蟲的技術總是想方設法地去區分人和程式,所以防止被封禁的核心思想就是儘量偽裝成正常的使用者,只要按著這個思想走,總能找到具體的方法。



作者:zgjx
連結:https://www.jianshu.com/p/5e7f8d75edbe
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授