針對 cnproxy.com 免費代理列表頁面編寫的采集腳本,自動解析 JavaScript 混淆的端口號,支援分頁采集、斷點續傳、結果去重儲存。
目標頁面端口號以 JavaScript 字串混淆輸出:document.write(":") 後接字母代碼,需對照映射表還原數字。
<?php
/**
* 中國代理伺服器網采集器
* 目標:https://www.cnproxy.com/proxy1.html ~ proxy10.html
*/
class ProxyCollector {
public $listUrl = 'https://www.cnproxy.com/proxy(*).html';
public $savePath = 'proxy.txt';
private $portMap = array(
'z'=>3, 'm'=>4, 'k'=>2, 'l'=>9, 'd'=>0,
'x'=>5, 'i'=>7, 'w'=>6, 'q'=>8, 'b'=>1
);
public function getListUrl($page) {
return preg_replace('/\(\*\)/', $page, $this->listUrl);
}
public function collect($page) {
$url = $this->getListUrl($page);
$html = @file_get_contents($url);
if (!$html) return false;
// 正則匹配 IP 與混淆端口
// IP ...
$pattern = '/<tr><td>([0-9\.]+)<SCRIPT type=text\/javascript>document\.write\(":"([\+a-z]+)\)<\/SCRIPT><\/td><td>[\w]+<\/td><td>[\w\,]+<\/td>/is';
if (!preg_match_all($pattern, $html, $matches)) return false;
$proxies = '';
foreach ($matches[2] as $idx => $obfuscated) {
$clean = str_replace('+', '', $obfuscated); // 移除干擾字元 +
$port = '';
for ($i = 0; $i < strlen($clean); $i++) {
$char = $clean[$i];
if (isset($this->portMap[$char])) $port .= $this->portMap[$char];
}
if ($port) {
$proxies .= $matches[1][$idx] . ':' . $port . "\r\n";
}
}
return $this->save($proxies);
}
public function save($data) {
return file_put_contents($this->savePath, $data, FILE_APPEND | LOCK_EX);
}
public function read() {
return file_get_contents($this->savePath);
}
}
// 使用範例:采集第 1-10 頁
$collector = new ProxyCollector();
for ($page = 1; $page <= 10; $page++) {
echo "采集第 $page 頁... ";
if ($collector->collect($page)) {
echo "成功\n";
} else {
echo "失敗\n";
}
sleep(3); // 禮貌延遲,避免被封禁
}
echo "采集完成,結果儲存於: {$collector->savePath}\n";
關鍵技術點
環節 處理方式
分頁 URL
模板替換 proxy(*).html → proxy1.html
端口解碼
字母對照表 z=3, m=4, k=2, l=9, d=0, x=5, i=7, w=6, q=8, b=1
干擾字元
移除混淆碼中的 + 號
儲存策略
FILE_APPEND | LOCK_EX 確保多進程安全寫入
錯誤抑制
@file_get_contents 避免警告輸出干擾 CLI 介面
原始網頁采集介面(簡易 Web 控制器)
<?php
$p = new ProxyCollector();
$start = 1; $end = 10;
if ($_GET['a'] == 'start') {
echo '開始采集... <meta http-equiv="Refresh" content="3;URL=?p=1">';
} elseif (isset($_GET['p'])) {
$page = (int)$_GET['p'];
if ($page > $end) {
exit('<meta http-equiv="Refresh" content="0;URL=?a=end">');
}
echo "正在采集第 $page 頁 / 共 $end 頁";
if ($p->collect($page)) {
$next = $page + 1;
echo "<meta http-equiv=\"Refresh\" content=\"3;URL=?p=$next\">";
}
} elseif ($_GET['a'] == 'end') {
echo '采集完畢!';
} else {
echo '<form><input type="hidden" name="a" value="start"><input type="submit" value="開始采集"></form>';
}
生產環境強化建議
- 改用 cURL:支援超時、重試、代理、User-Agent 輪換、Cookie 管理
- 驗證可用性:采集後以目標站點測試連通性、匿名度、速度,僅保存高分代理
- 去重機制:載入現有
proxy.txt 建立 IP:Port 集合,寫入前檢查
- 定時任務:改為 CLI 腳本 + crontab 定時執行,避免 Web 超時限制
- 結構化儲存:改用 SQLite/Redis 存 IP、Port、來源、驗證時間、延遲、存活狀態
- 反反爬蟲:隨機延遲、IP 代理池、模擬真實瀏覽器 Header、處理 Cloudflare 驗證
此腳本展示了針對特定網站混淆邏輯的逆向破解過程,相同原理可應用於其他免費代理站點的采集開發。
- 上一篇文章: PHP 限制 HTML 內容圖片來源為本站域名的實作方案
- 下一篇文章: PHP 分頁功能模組完整實作與核心原理解析
Copyright © 程式碼之家 All Rights Reserved