天天看點

常見的反爬措施:UA反爬和Cookie反爬

摘要:為了屏蔽這些垃圾流量,或者為了降低自己伺服器壓力,避免被爬蟲程式影響到正常人類的使用,開發者會研究各種各樣的手段,去反爬蟲。

本文分享自華為雲社群《​​Python爬蟲反爬,你應該從這篇部落格開啟,UA反爬,Cookie 特定參數反爬​​》,作者:夢想橡皮擦。

你或許已經注意到,對于目标站點來說,爬蟲程式是機器通路,從目标站點的角度來看,爬蟲帶來的流量都是“垃圾流量”,是完全沒有價值的(刷量類爬蟲除外)。

為了屏蔽這些垃圾流量,或者為了降低自己伺服器壓力,避免被爬蟲程式影響到正常人類的使用,開發者會研究各種各樣的手段,去反爬蟲。

爬蟲與反爬蟲是一對共生關系,有爬蟲工程師,就必然存在反爬工程師,很多時候,爬蟲工程師與反爬工程師都在鬥智鬥勇。

反爬沒有特定的分類,如果一個網站上了反爬代碼,一般情況下會使用幾種反爬措施搭配使用。

伺服器驗證請求資訊類爬蟲

本系列的部落格從最簡單的反爬手段開始學習,入門級反爬:“User-Agent” 使用者代理反爬。

User-Agent

使用者代理(User-Agent),表示的是使用者的浏覽器相關資訊,該反爬邏輯是通過伺服器端驗證請求頭中的 User-Agent 參數,然後區分是爬蟲程式還是正常的浏覽器通路。

通路任意網站,喚醒開發者工具,然後在控制台中輸入 navigator.userAgent,就可以擷取到 UA 字元串(User-Agent 字元串)。

常見的反爬措施:UA反爬和Cookie反爬

UA 字元串的格式一般可以這麼了解:

平台 引擎版本 浏覽器版本資訊      

如果在詳細分解,可以得到如下格式:

浏覽器辨別 (作業系統辨別;加密等級;浏覽器語言) 引擎版本 浏覽器版本資訊      

這樣你在看上圖所示的内容,就比較容易了解其含義了。

Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36      

在不同的浏覽器測試,你會發現 UA 字元串都以 Mozilla 開頭,這是由于曆史上的浏覽器大戰,導緻的遺留問題。

下面對比市面上主流的三款浏覽器的 UA 字元串。

# 谷歌浏覽器
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
# 火狐浏覽器
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
# IE11 浏覽器
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko      

分析上述内容中的相關資料含義

  • Mozilla/5.0:表示浏覽器;
  • Windows NT 6.1:作業系統,我這裡得到的是 Windows 7 作業系統;
  • Win64/WOW64:64 位作業系統;
  • x64:發行版本;
  • N,I,U:加密等級,這裡沒有出現;
  • AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36:這個如果你去研究,也有很多趣事,不過咱們了解其是浏覽器的版本就可以了。

有了基本的認知之後,我們就可以任意的去編寫不同的浏覽器辨別了(多數時候是從開發者工具中直接複制)

相應的,伺服器也能從這個字元串中,識别出通路它的浏覽器相關資訊(其實作業系統的資訊也會被攜帶過去,甚至它可以驗證該 UA 字段是否複合特定的規則)

案例實操環節

拿 CSDN 熱榜進行測試,如果不設定 UA 字段,你将擷取不到任何傳回資料,你可以将下述 headers 置為空值,然後檢視運作結果。

import requests

headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"
}
res = requests.get('https://blog.csdn.net/phoenix/web/blog/hot-rank?page=0&pageSize=25', headers=headers)
print(res.text)      

User-Agent 生成

可以使用 Python 第三方庫,pip install fake_useragent,也可以自己維護一個 UA 類。與 User-Agent 參數相同的還有 HOST 與 Referer,都可以認為的設定一些資訊進行反爬。

Cookie 反爬蟲

使用 Cookie 驗證,也是常見的反爬,由于目标站點可遇不可求,是以接下來的内容從理論層面說明,在後續會結合複雜的案例進行實操。

Cookie 反爬蟲最簡單的手段

伺服器端使用特殊的 Cookie 值進行驗證,如果發現傳遞過去的 Cookie 值不存在,或者不符合生成規範,則不傳回資料。

例如伺服器驗證固定 Cookie 字段,在前文擷取熱榜代碼中,如果你不攜帶某些 Cookie 值,那得到的就不是完整的資料(可自行測試,差異值為 username)。

還有一種情況是驗證 Cookie 是否符合某種格式,例如 Cookie 由 JS 動态生成,而且複合某種潛在(開發者約定)的規則,那該 Cookie 值傳遞到背景之後,背景工程師直接驗證該值即可實作反爬效果,例如 Cookie 規則為 123abc123,前面 3 個随機數,後面 3 個随機數,中間三個随機小寫字母,那背景工程師就可以通過正則驗證用戶端傳遞的 Cookie 值,是否複合規則,不符合,直接傳回異常資訊。

當然這種手段很容易被識别出來,進一步還可以加入時間戳,背景工程師拿到 Cookie 中的時間戳之後,驗證目前時間的內插補點,如果超過了某個值,也可以認為該 Cookie 是僞造的。

Cookie 還被用于使用者身份的驗證,例如很多站點的資料隻有登入之後才可以通路,原因是 Cookie 記錄了使用者資訊,Cookie 的這個應用場景比較多,例如華為雲部落格的系統消息頁面

​​https://developer.huaweicloud.com/usercenter/mysysmessage​​

import requests
from lxml import etree

headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36",
    "cookie": '你的HWS_ID Cookie值;'
}
res = requests.get('https://developer.huaweicloud.com/usercenter/mysysmessage', headers=headers, allow_redirects=False)
with open("./1.html", "w", encoding="utf-8") as f:
    f.write(res.text)
elements = etree.HTML(res.text)
print(elements.xpath("//title/text()"))