笑話集網站數據采集 PHP 類實作
<?php
include_once('writeLog.php');
class Joke {
public $jokeText = '';
public $urlNext = '';
public $urlPrv = '';
public $urlBase = 'https://wap.jokeji.cn/';
public function __construct() {}
// 獲取並解析內容頁
public function getContent($url) {
MyLog('url.log', $url);
// 網站編碼為 gb2312,需轉 UTF-8
$html = file_get_contents(iconv('gb2312', 'UTF-8', $url));
// 提取笑話正文
$begin = stripos($html, '<div class="joketxt">') + 23;
$end = stripos($html, '<script', $begin);
$text = substr($html, $begin, $end - $begin);
$text = str_ireplace(['<p>', '</p>', '<br>'], ['', '', "\r\n"], $text);
$this->jokeText = $text;
// 提取上一篇鏈接
$begin = stripos($html, '上一篇:<a');
if ($begin !== false) {
$begin += 27;
$end = stripos($html, '"', $begin);
$this->urlNext = substr($html, $begin, $end - $begin);
}
// 提取下一篇鏈接
$begin = stripos($html, '下一篇:<a');
if ($begin !== false) {
$begin += 27;
$end = stripos($html, '"', $begin);
$this->urlPrv = substr($html, $begin, $end - $begin);
}
}
// 獲取列表頁第一條鏈接
public function getFirstLink() {
$html = file_get_contents($this->urlBase);
$begin = stripos($html, '<div class="list">') + 42;
$end = stripos($html, '"', $begin);
return substr($html, $begin, $end - $begin);
}
// 統一入口:返回結構化數據
public function getJoke($u = '') {
$url = $u ?: $this->urlBase . $this->getFirstLink();
$this->getContent($url);
return [
'content' => $this->jokeText,
'next' => $this->urlNext,
'previous' => $this->urlPrv,
];
}
}
// 使用示例:
// $joke = new Joke();
// $data = $joke->getJoke();
// var_dump($data);
?>
關鍵點說明
- 編碼轉換: 目標站為 GB2312,採集前必須
iconv('gb2312', 'UTF-8', $url),否則中文亂碼。
- 定位策略: 使用
stripos 定位特徵標籤(<div class="joketxt">、上一篇:),再按相對偏移截取,結構簡單但依賴頁面結構穩定。
- 清洗處理: 移除
<p>, </p>,將 <br> 替換為換行符,得到純文本笑話內容。
- 翻頁邏輯: 同時提取「上一篇」與「下一篇」鏈接,支援雙向遍歷采集。
擴展建議
- 加入請求間隔(
sleep())避免觸發反爬蟲。
- 使用 cURL 替代
file_get_contents,支援 Cookie、Header、超時控制。
- 異常捕獲與重試機制,增強穩健性。
- 將數據入庫(MySQL/MongoDB/Redis)而非僅日志記錄。