此分享只用於學習用途,不作商業用途,若有冒犯,請聯絡處理
反爬前置資訊
站點:aHR0cHM6Ly9jenFqZC5qc3p3ZncuZ292LmNuL2tkY3B1YXBvcnRhbC8jLw==
介面:/kong/InnerGateway/kdcpua/lib/project/publicity
反爬機制定位
在抓取某個站點時,我們需要找到目標介面,然後確定目標介面所使用的反爬機制,常見反爬機制有cookie
、請求頭
、簽名校驗
等,只有找到它所使用的反爬機制我們才能對點下藥。
找到對應的介面,右鍵複製其cUrl
,然後使用爬蟲工具庫將其轉成python requests程式碼
,這樣便於我們快速進入除錯定位反爬機制
可以看到它只存在兩個變數,就是cookie
和請求頭
,接下來使用控制變數法,結果如下:
- 請求傳入headers,傳入cookie,請求成功
- 請求不傳入headers,傳入cookie,請求失敗
- 請求傳入headers,不傳入cookie,請求成功
- 請求不傳入headers,不傳入cookie,請求成功
根據結果確定它的反爬機制只有請求頭
大家看下,紅色橫線對應的那些請求頭不會是檢測點,而像Accept
,Accept-Language
,Referer
,User-Agent
都是可以寫死的,大家可能會說User-Agent
也是反爬機制,User-Agent
確實可以反爬,不過它的反爬機制對應的是採集頻率,我們現在是請求請求前的反爬
剔除這些後,剩下的Authorization
,Token
,x-date
就很明顯是動態生成且容易作為檢測點了,這裡Token
不需要關注,我們測試一下Authorization
,x-date
,結果如下:
- 保留
Authorization
,保留Token
,請求成功 - 保留
Authorization
,不保留Token
,請求失敗 - 不保留
Authorization
,保留Token
,請求失敗 - 不保留
Authorization
,不保留Token
,請求失敗
結果兩次測試結果可以確定Authorization
,Token
是檢測點且兩者之間存在關係。透過這種方法我們最終確定了介面的反爬機制,接下來就是如何破解它了。
逆向研究
這個站點沒有特別的混淆,全域性搜尋x-date
直接鎖定關鍵程式碼位置,它是一個原生的hmac-sha256
加密,加密文字就是x-date
,x-date
是UTC時間字串
演算法破解
import base64
import hashlib
import hmac
from datetime import datetime
import requests
def get_hmac_authorization():
hit_time = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
key = '1S7JzAkstxUV1g51IB22otDrwRkFxRJ3'.encode()
message = 'x-date: {}'.format(hit_time).encode()
hmac_sha256 = hmac.new(key, message, digestmod=hashlib.sha256)
hmac_digest = hmac_sha256.digest()
encrypt_result = base64.b64encode(hmac_digest).decode()
return {
'Authorization': 'hmac username="kdcpua", algorithm="hmac-sha256", headers="x-date", signature="{}"'.format(
encrypt_result),
'x-date': hit_time,
}
headers = {
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.9",
"Origin": "Origin",
"Referer": "Referer",
"Token": "undefined undefined",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
}
headers.update(get_hmac_authorization())
url = "url "
response = requests.post(url, headers=headers)
print(response.text)