聲明
本文所討論的內容及技術均純屬學術交流與技術研究目的,旨在探討和總結互聯網數據流動、前后端技術架構及安全防御中的技術演進。文中提及的各類技術手段和策略均僅供技術人員在合法與合規的前提下進行研究、學習與防御測試之用。
作者不支持亦不鼓勵任何未經授權的工程應用或違法行為,所有內容均不構成任何非法操作的技術指導或建議。請各位讀者根據所在平臺的相關規定及法律法規謹慎使用和解讀本文內容。
引言
在過去的六篇文章中,我們以“庖丁解牛”的方式拆解了反爬蟲攻防的核心邏輯,從協議分析、行為特征檢測到動態渲染對抗,逐步構建了一套完整的反爬蟲技術設計框架。
從這一篇開始,一切將截然不同,我們將以代碼說話。
設計是技術的骨架,而開發才是賦予其血肉與靈魂的過程。本文將帶領讀者正式跨越理論與實踐的邊界,進入實戰開發階段。我們將親手實現一個輕量指紋瀏覽器SDK,并深度集成瀏覽器自動化工具(如Puppeteer、Playwright)。
接下來的內容將默認讀者已掌握Python/JavaScript基礎及HTTP協議核心知識。
接口設計
在設計SDK接口時,我反復澄清要給到最終使用者的是什么?更多功能?還是更簡單易用?在這里,我選擇了更加傾向于易用性。畢竟我們的程序,是要解決問題,降低復雜度,而非制造問題。因此我們在設計瀏覽器模塊接口時,只關注以下幾個動作:
- 創建一個瀏覽器實例
- 關閉瀏覽器實例,并回收相關資源
- 查看當前正在運行中的瀏覽器實例
這些行為,已經完全可以滿足一個爬蟲在執行過程中所需進行的全部動作了。因為在瀏覽器實例創建完畢之并與爬蟲框架完成CDP連接之后,后續的就都是爬蟲系統的行為了。
接口文檔
由于我們是指紋瀏覽器,因此我們先把指紋模型的設計放在最開始
指紋數據
{"screen": {"width": 800, // 寬度"height": 600 // 高度},// 屏幕分辨率 非必填"timezone": "Asia/Hong_Kong",// 時區,非必填"userAgent": "Mozilla/5.0 (Windows NT 10.0; WOW64) Chrome/86.0.4240.198", // UA信息 非必填"platform": "Win32",// 平臺信息 非必填"userAgentData": {"productName": "Google Chrome", //瀏覽器品牌名 Google Chrome / Microsoft Edge / Chromium / Brave"productVersion": "110.0.5481.78", // 瀏覽器版本號"isMobile": false, // 是否為手機版 "platform": "Windows", // 運行平臺 Windows/Mac OS X/Linux/iOS/Android"platformVersion": "15.0.0", // 運行平臺版本號 Windows 舉例 Win11:15.0.0 /Win10: 10.0.0"architecture": "x86", // 編譯架構 arm/x86"bitness": "64", //運行平臺 位數 32/64"model": "", //品牌型號,僅限手機版情況下有值"wow64": false // 99 以下 undefined,99 以上 false(僅win有判斷,其他系統統一false)},// UAData信息 非必填 但UA發生變化時必填,同時會校驗此信息合法性"deviceMemory?": 8, // 設備內存 非必填"hardwareConcurrency?": 4, // 硬件并發數 非必填"languages": ["en-US",], // 頁面語言 非必填"locale": "en-US", // UI語言 非必填},"font": {"unicode": true, //是否禁用Emoji表情,true|false"fonts": ["Arial","Arial Black","Arial Narrow","Calibri","Cambria","Cambria Math","Comic Sans MS"],// 字體列表}, // 字體信息 非必填"audio": {"seed": "xxxxx"},// 音頻指紋噪聲 非必填"canvas": {"seed": "xxxxx"},// Canvas指紋噪聲 非必填"webgl": { "seed": "xxxxx", // 噪聲 非必填"meta":{"vendor": "Google Inc.", // 提供商"renderer": "ANGLE (NVIDIA GeForce GT 730)" // 渲染器} //元數據 非必填},// WebGL配置 非必填"geolocation": {"latitude": 44.0,"longitude": 55.0},// 定位信息 非必填"bluetooth": { "enabled": false // 是否啟用藍牙,true or false},// 藍牙狀態 非必填"speech": [// 至少有一項的is_default為true !// 否則朗讀者列表強制轉化為空,顯示為blocked{"name": "Microsoft Swara - Hindi (India)", // 朗誦者名稱,字符串"lang": "hi-IN", // 朗誦者語言,字符串"isDefault": true // 是否為默認語音,true or false},{"name": "Microsoft Sylvie - French (Canada)","lang": "fr-CA","isDefault": false}]// 朗讀者列表 非必填}
以上是我們指紋部分支持的全部配置,通過這些指紋的排列組合,我們已經可以很好的確定瀏覽器實例的指紋唯一性了,下面我們來繼續完善其他操作的文檔。
新建瀏覽器實例
API
路徑 | 請求方式 |
/browsers | POST |
Request
{"userDataDir":"", // 數據緩存路徑 必填"proxy":{"protocol":"http",// 協議 支持http,https,socks 必填"host":"39.123.33.154",// 代理主機 支持 IPv4 IPv6 以及域名 必填"port":10234,// 代理端口 必填"username":"",// 用戶名 非必填"password":"",// 密碼 非必填},//代理 非必填"args":[],// 瀏覽器附加的命令行參數,非必填 會過濾掉 --proxy-server --remote-debugging-port"metadata":{},//用戶存儲的元數據,非必填"fingerprint":{},// 指紋數據,非必填 無指紋數據時則不會對指紋進行模擬。
}
Response
{"id":"xxxx-xxxx-xxxx-xxxx-xxxx", // 瀏覽器實例ID"proxyUrl":"http://127.0.0.1:11111",// 瀏覽器使用的本地轉發后的代理鏈接"args":[],// 瀏覽器附加的參數"metadata":{},// 用戶緩存的元數據"automation":{"driverPath":"",// 瀏覽器匹配的WebDriver路徑"remoteDebuggingPort":32023,// 遠程調試端口"cdpUrl":"http://127.0.0.1:32023",// CDP連接路徑"cdpWsUrl":"ws://localhost:32023/devtools/page/DAB7FB6187B554E10B0BD18821265734",// CDP Websocket連接路徑},// 自動化相關信息"createdTime":""// 創建時間
}
關閉瀏覽器實例
API
路徑 | 請求方式 |
/browsers/{browserId} | DELETE |
Response
{"id":"xxxx-xxxx-xxxx-xxxx-xxxx", // 瀏覽器實例ID"proxyUrl":"http://127.0.0.1:11111",// 瀏覽器使用的本地轉發后的代理鏈接"args":[],// 瀏覽器附加的參數"metadata":{},// 用戶緩存的元數據"automation":{"driverPath":"",// 瀏覽器匹配的WebDriver路徑"remoteDebuggingPort":32023,// 遠程調試端口"cdpUrl":"http://127.0.0.1:32023",// CDP連接路徑"cdpWsUrl":"ws://localhost:32023/devtools/page/DAB7FB6187B554E10B0BD18821265734",// CDP Websocket連接路徑},// 自動化相關信息"createdTime":""// 創建時間
}
關閉全部瀏覽器實例
API
路徑 | 請求方式 |
/browsers | DELETE |
Response
{"id":"xxxx-xxxx-xxxx-xxxx-xxxx", // 瀏覽器實例ID"proxyUrl":"http://127.0.0.1:11111",// 瀏覽器使用的本地轉發后的代理鏈接"args":[],// 瀏覽器附加的參數"metadata":{},// 用戶緩存的元數據"automation":{"driverPath":"",// 瀏覽器匹配的WebDriver路徑"remoteDebuggingPort":32023,// 遠程調試端口"cdpUrl":"http://127.0.0.1:32023",// CDP連接路徑"cdpWsUrl":"ws://localhost:32023/devtools/page/DAB7FB6187B554E10B0BD18821265734",// CDP Websocket連接路徑},// 自動化相關信息"createdTime":""// 創建時間
}
查看當前所有正在運行的瀏覽器實例
API
路徑 | 請求方式 |
/browsers | GET |
Response
[{"id":"xxxx-xxxx-xxxx-xxxx-xxxx", // 瀏覽器實例ID"proxyUrl":"http://127.0.0.1:11111",// 瀏覽器使用的本地轉發后的代理鏈接"args":[],// 瀏覽器附加的參數"metadata":{},// 用戶緩存的元數據"automation":{"driverPath":"",// 瀏覽器匹配的WebDriver路徑"remoteDebuggingPort":32023,// 遠程調試端口"cdpUrl":"http://127.0.0.1:32023",// CDP連接路徑"cdpWsUrl":"ws://localhost:32023/devtools/page/DAB7FB6187B554E10B0BD18821265734",// CDP Websocket連接路徑},// 自動化相關信息"createdTime":""// 創建時間
}]
以上就是全部的接口設計文檔了。
使用案例
下面我們以用戶的角度,來使用我們的SDK,以下是一個基于Python與Playwright框架的簡單例子。
import requests
from playwright.sync_api import sync_playwright# API信息
api_url = "http://localhost:3000/browsers" # 假設這是我們SDK服務的地址# 請求數據
request_data = {"userDataDir": "/path/to/user/data", # 請替換為實際的數據緩存路徑"proxy": {"protocol": "http","host": "39.123.33.154","port": 10234,"username": "","password": ""},"args": [],"metadata": {"description":"一個演示用的實例"},"fingerprint": {"screen":{"width":800,"height":600},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36","userAgentData": {"productName": "Google Chrome", "productVersion": "133.0.6943.142", "isMobile": false, "platform": "Windows", "platformVersion": "15.0.0", "architecture": "x86", "bitness": "64", "model": "", "wow64": false}}
}# 發送POST請求創建瀏覽器實例
response = requests.post(api_url, json=request_data)# 檢查響應狀態碼
if response.status_code == 200:response_data = response.json()print("瀏覽器實例創建成功:")print(response_data)# 獲取CDP連接信息cdp_ws_url = response_data["automation"]["cdpWsUrl"]# 使用Playwright連接到瀏覽器實例with sync_playwright() as p:browser = p.chromium.connect_over_cdp(cdp_ws_url)# ... Todoelse:print(f"請求失敗,狀態碼: {response.status_code},錯誤信息: {response.text}")
以上就是一個使用SDK的簡單示例,我們在啟動時,提供了一個基于Http協議的代理,以及提供了屏幕大小、UA的指紋模擬。并在啟動完成之后,通過cdpWsUrl,將瀏覽器實例與Playwright進行連接,最終完成我們的爬蟲操作。
總結
本文從理論到實踐,詳細介紹了一個輕量級指紋瀏覽器SDK的設計與實現。文章強調了易用性,將SDK功能聚焦于創建、關閉和查看瀏覽器實例三個核心操作。文中詳細說明了指紋數據模型結構,包括屏幕分辨率、用戶代理、平臺信息等多個維度,確保瀏覽器實例的唯一性。
接口設計部分提供了完整的API文檔,并通過一個Python和Playwright的案例展示了實際應用。這一實現不僅將之前討論的反爬蟲理論付諸實踐,還為開發者提供了一個靈活、易用的工具,幫助他們在復雜的反爬蟲環境中更有效地進行數據采集工作。并成功地將復雜的反爬蟲技術轉化為可操作的開發實踐,為讀者搭建了理論與實踐之間的橋梁。