程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python crawler engineers here, do you dare to crawl the site of a law firm?

編輯:Python

Table of Contents

    •  ️ 實戰場景
    •  ️ 反爬實戰
    •  ️ 反爬總結

️ 實戰場景

本次要分析的站點是 credit.acla.org.cn/,一個律師群體常去的站點,作為一個爬蟲工程師,這簡直是送自己去喝茶.


該站點反爬手段特別多,分析起來也特別有趣.

️ 反爬實戰

打開開發者工具,無限 debugger

(function anonymous() {
debugger;
});

  • 1.
  • 2.
  • 3.

直接行號處右鍵一律不在此處暫停

字體反爬
切換到 Elements 視圖,很容易就發現了字體反爬的存在.

由於我們之前的博客涉及了大量字體反爬內容,本文就不在展開說明了.

控制台清空
接下來還出現了一個小細節,該站點在不斷的執行清空控制台數據操作,也就是它不讓你進行控制台測試.

這一點反爬也很容解決,使用下述代碼即可.

// 取消清空方法
console._c = console.clear;
console.clear = function () {
return;
};

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.


此時日志還會一直出現,需要取消日志輸出.

console._l = console.log;
console.log = function () {
return;
};

  • 1.
  • 2.
  • 3.
  • 4.


此時 <img /> 也不會再次輸出.

類 JSFUCK 加密反爬

簡單的反爬手段已經解決了,下面開始嘗試獲取網頁數據,測試代碼如下所示.


import requests
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"referer": "https://credit.acla.org.cn/"
}
res = requests.get('https://credit.acla.org.cn/credit/lawFirm?picCaptchaVerification=&keyWords=',headers=headers)
print(res.text)

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

運行代碼,結果得到下述響應內容.

這加密長得特別像 jsfuck 加密,對於它的具體加密形式,其實不需要特別關注,我們只需要通過控制台查看對應內容即可.

注意不要在 Pycharm 等工具的控制台直接復制代碼去開發者工具中運行,要寫入文件,然後復制整行內容.

在打開一個站點的控制台,例如百度,然後喚醒控制台,刪除 $=~[]……() 代碼段最後的 (),然後執行.


解析代碼之後,可以查看代碼詳情,其中涉及了多次 cookie 設置.

再次訪問目標站點,分析之後,發現 lawFirm 地址被調用了兩次,第一次返回的就是上述加密內容,因此可以得到結論,首次訪問是獲取 cookie,二次請求才是真實數據.

測試發現第二次請求果然所有 cookie 都進行了發送.

解析 JS 代碼,原計劃使用 execjs 模塊,但是發現其無法解析,沒辦法只能切換為 py_mini_racer.

PyMiniRacer 是適用於 Python 的最小的現代嵌入式 V8.PyMiniRacer 支持最新的 ECMAScript 標准,支持 Assembly,並提供可重用的上下文.

本部分代碼如下所示.


import requests
import re
from py_mini_racer import MiniRacer
import execjs
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36",
"referer": "https://credit.acla.org.cn/credit/lawFirm?picCaptchaVerification=&keyWords="
}
res = requests.get('https://credit.acla.org.cn/credit/lawFirm?picCaptchaVerification=&keyWords=',headers=headers)
# with open('aaa.html', 'w') as f:
# f.write(res.text)
pattern = re.compile('(\$\=\~\[\];.*?[\s\S]*)</script>')
data = pattern.findall(res.text)[0]
# print(data[0])
script_str = data[:-1].strip()
script_str = script_str.replace('();','')
""" # 刪除最終的自執行代碼 script_str = script_str.replace(')();','') # 刪除包裹函數 script_str = script_str.replace(';$.$(',';') """
ctx = MiniRacer()
print(script_str)
print(ctx.eval(script_str))

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.

代碼輸入如下內容:

這裡出現了一個 JSFunction 對象,代表代碼 JS 代碼被執行了,解決辦法在上述代碼也存在,就是刪除自執行部分代碼.

# 刪除最終的自執行代碼
script_str = script_str.replace(')();','')
# 刪除包裹函數
script_str = script_str.replace(';$.$(',';')

  • 1.
  • 2.
  • 3.
  • 4.

再次運行,得到解密後的 JS 代碼.

跳轉鏈接反爬
原以為本站點的所有反爬都已經解決了,結果當點擊事務所詳情頁的時候,發現地址也被加密了.


這個地方斷點下的很有趣,因為該點擊事件是通過 onclick 綁定到標簽上的,所以添加斷點的方式是通過事件定位之後,添加到 DOM 元素上.

打斷點效果~

再次點擊詳情頁,可以進入該斷點,稍加調試即可發現核心加密函數.

提取加密函數核心代碼,如下所示,一個簡單的 DES_ECB 加密.

function decryptByDES(ciphertext, key) {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var decrypted = CryptoJS.DES.decrypt(
{
ciphertext: CryptoJS.enc.Base64.parse(ciphertext),
},
keyHex,
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
);
return decrypted.toString(CryptoJS.enc.Utf8);
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

剩下的事情就是秘鑰 keyHex 的獲取,這部分稍加調試即可實現.

️ 反爬總結

實在沒有想到,一個站點的搜索頁面竟然存在如此多的反爬手段,看來律師事務所的數據,實在是不易采集,大家加油,版權問題,無法放出完整代碼,如需獲取,請點擊卡片.


你正在閱讀 【夢想橡皮擦】 的博客
閱讀完畢,可以點點小手贊一下
發現錯誤,直接評論區中指正吧
橡皮擦的第 <font color=red>689</font> 篇原創博客


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved