file_get_contents($url) 獲取頁面 HTML(需 allow_url_fopen=On)。preg_match_all() 批次匹配目標區塊(列表頁的章節連結與標題)。cut($str, $start, $end) 從匹配片段中精確截取所需字串。function cut($string, $start, $end) {
$msg = explode($start, $string, 2);
if (isset($msg[1])) {
$msg = explode($end, $msg[1], 2);
return $msg[0];
}
return '';
}
$html = file_get_contents('https://example.com/Html/Book/123/List.shtm');
$typeid = cut($html, 'Html/Book/', 'List.shtm'); // 取得 '123'
// 匹配所有章節連結:第1章 開端 preg_match_all('/<a href="(\d+\.shtm)">(.*?)<\/a>/is', $html, $matches); $urls = $matches[1]; // ['456.shtm', '457.shtm', ...] $titles = $matches[2]; // ['第1章 開端', '第2章 發展', ...] $chapters = []; foreach ($urls as $i => $url) { $chapters[$url] = trim($titles[$i]); } // $chapters = ['456.shtm' => '第1章 開端', ...]
foreach ($chapters as $url => $title) {
$chapterHtml = file_get_contents("https://example.com/Html/Book/$typeid/$url");
// 提取正文區塊(假設在 <div id="content">...</div>)
$content = cut($chapterHtml, '<div id="content">', '</div>');
// 清洗廣告、換行、特殊字元
$content = strip_tags($content, '<p><br>');
$content = str_replace([' ', ' '], ' ', $content);
// 儲存資料庫或檔案
saveChapter($title, $content);
usleep(200000); // 禮貌延遲 0.2 秒,避免被封 IP
}
curl_multi_exec 或 GuzzleHttp\Pool 並發請求,效率提升 10 倍+。mb_convert_encoding($html, 'UTF-8', 'auto') 統一轉 UTF-8。采集器僅供技術學習與個人合理使用。商業用途請遵守 robots.txt、網站服務條款、著作權法;優先申請官方 API 或授權。