李陽的手指剛碰上回車鍵,屏幕上的進度條還沒來得及跳動,警報聲就刺了進來。
紅色彈窗在主控台右下角炸開:“數據源中斷——目標站點返回403,IP已列入黑名單。”
陳帆猛地抬頭,盯著那行字看了兩秒。他沒說話,但身體已經轉了過來,手指迅速調出網絡請求日誌。一行行記錄飛速滾動,每一條都標記著同一個出口IP地址,而最後一次響應時間停留在五秒前。
“不是偶然。”他說,“他們開始盯IP了。”
張遠從副機位探身過來,眼睛還帶著昨晚熬過頭的紅絲,“我們才發了不到二十個請求,這就被封了?”
“不是數量問題。”李陽快速打開抓包工具,重放最近一次會話流程,“是行為模式被識彆了。三次連續請求後,服務器直接切斷連接,連驗證碼都沒走。”
陳帆站起身,走到SGI工作站旁,看了一眼集群狀態麵板。“單點代理撐不住了。現在得換方式——用分布式節點輪換。”
“可我們哪有那麼多可用IP?”張遠皺眉。
“實驗室有三十台終端,校外還有幾個合作節點。”陳帆語速平穩,“加上之前收集的公開代理池,湊一百個不難。關鍵是調度機製要改。”
“我來寫驗證腳本。”張遠坐回去,打開編輯器,“先篩一遍可用節點,標記延遲和穩定性。”
“彆急著跑全量。”陳帆提醒,“先做心跳探測,確認哪些還能通。”
李陽已經開始重構爬蟲調度邏輯。他新建了一個Python腳本框架,準備把整個代理池納入異步協程管理。“用隨機間隔發起請求,每次換不同UA,避免特征固化。”
三人分工落定,機房重新進入高速運轉節奏。
半小時後,張遠敲下最後一行代碼,運行檢測程序。屏幕上跳出一個列表,一百零七個IP地址逐個測試連接狀態。前五十個接連失敗,第六十七個起出現斷續響應,最終篩選出八十九個標為“臨時可用”。
“成功率低是低了點,”他抹了把臉,“但總比沒有強。”
陳帆點頭:“先接入這批,試試看能不能打通鏈路。”
李陽將新代理列表導入調度器,啟動輕量級抓取任務。係統開始自動輪換IP,每請求一次便切換出口地址。初始幾條數據成功返回,頁麵結構完整,字段清晰。
“成了?”張遠盯著第一條入庫記錄,聲音裡透出點興奮。
話音未落,監控曲線驟然下跌。
成功率從98%直墜為零。日誌區瘋狂刷出“ConnectionResetbyPeer”,所有正在活動的節點幾乎在同一時間失去響應。
“全被封了?”張遠猛地站起來,“這才幾分鐘!”
陳帆迅速調出失敗記錄的時間軸,眉頭一沉。“不對……這批IP是在三分鐘內集中失效的。說明對方不隻是封單個地址,而是追蹤到了整個代理組的行為關聯。”
“問題出在哪?”李陽問。
“出在我寫的驗證邏輯。”張遠臉色變了。他翻出自己剛才的腳本,一行行檢查,“我把測試成功的IP直接標記為‘健康’,沒加二次驗證。有些節點其實是中轉網關,真實出口早就變了——我們等於一直在用一組已經被標記過的舊路徑。”
陳帆沉默片刻,下令:“停掉所有主動抓取任務,隻保留最低頻次的心跳探測,頻率拉到每五分鐘一次,每個IP隻用一次。”
“不能再暴露更多資源。”他說。
李陽立刻修改調度策略,關閉批量任務隊列。同時,他調用SGI集群底層權限,嘗試從校園網段動態生成臨時虛擬出口。這種操作原本用於內部負載均衡,但從技術原理上看,可以模擬出多個獨立訪問源。
“如果能繞過公網IP綁定,就能讓每次請求看起來來自不同設備。”他說。