首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

CodeIgniter 爬蟲實戰:抓取新聞標題、內容、來源與圖片完整方案

     編輯:關於C語言

專案背景

本文整理一個基於 **CodeIgniter 3** 框架的網頁爬蟲控制器,目標站點為某二手車新聞列表頁。功能涵蓋:分頁列表遍歷、詳情頁解析、圖片下載與本地化替換、資料入庫。程式碼經過重構註解,適合作為 CI 爬蟲開發參考範本。

核心控制器程式碼


benchmark->mark('code_start');

        // 1. 遍歷 4 個新聞分類
        for ($i = 1; $i <= 4; $i++) {
            $url = 'https://news.2sche.cn/list.asp?stype=' . $i;
            $result = $this->curl_snatch($url);

            // 2. 解析總頁數
            preg_match_all('/\d\/(.*?)<\/strong>/', $result, $page_news);
            $total_pages = isset($page_news[1][0]) ? (int)$page_news[1][0] : 1;

            // 3. 遍歷每一分頁
            for ($j = 1; $j <= $total_pages; $j++) {
                $url_news = ($j == 1)
                    ? 'https://news.2sche.cn/list.asp?stype=' . $i
                    : 'https://news.2sche.cn/list.asp?page=' . $j . '&stype=' . $i;

                $result_news = $this->curl_snatch($url_news);

                // 4. 提取列表頁每篇新聞連結
                preg_match_all(
                    '/.*?<\/a><\/td>/sim',
                    $result_news,
                    $url_newslist
                );

                foreach ($url_newslist[1] as $url_newslists) {
                    $url_newsinfo = 'https://news.2sche.cn/' . $url_newslists;
                    $result_newsinfo = $this->curl_snatch($url_newsinfo);

                    // 5. 解析詳情頁欄位
                    preg_match_all('/

(.*?)<\/strong><\/h3>/sim', $result_newsinfo, $title); preg_match_all('/【來源:(.*?) 】<\/span><\/td>/sim', $result_newsinfo, $source); preg_match_all('/(.*?)<\/td>/sim', $result_newsinfo, $content); // 6. 提取內容區塊圖片 preg_match_all('//sim', $content[1][0], $img); $picture = ''; foreach ($img[1] as $imgs) { // 僅處理完整 HTTP 連結 if (strpos($imgs, 'https://') === false) continue; $img_source = file_get_contents($imgs); $img_name = trim(strrchr($imgs, '/'), '/'); // 7. 圖片本地化儲存 $save_path = "./static/uploads/news/" . $img_name; file_put_contents($save_path, $img_source); // 8. 內容中圖片連結替換為本地路徑 $local_path = '/static/uploads/news/' . $img_name; $content[1][0] = str_replace($imgs, $local_path, $content[1][0]); $picture .= $img_name . ':'; // 以冒號分隔多圖 } // 9. 組裝資料入庫 $data = [ 'title' => $title[1][0] ?? '', 'source' => $source[1][0] ?? '', 'contents' => trim($content[1][0] ?? ''), 'picture' => $picture, 'style' => $i, 'create_time' => time(), ]; if (!$this->News_model->add($data)) { continue; // 入庫失敗跳過 } } echo '
'; } } $this->benchmark->mark('code_end'); echo $this->benchmark->elapsed_time('code_start', 'code_end'); } // 通用 cURL 封裝:支援 GBK 轉 UTF-8、自動追蹤重導向 private function curl_snatch($url = 'https://www.2sche.cn/buy.asp') { $url = trim($url); $content = ''; if (extension_loaded('curl')) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_HEADER, 0); $output = curl_exec($ch); $content = iconv("GBK", "UTF-8", $output); if ($output === FALSE) { log_message('error', "cURL Error: " . curl_error($ch)); } curl_close($ch); } else { $content = file_get_contents($url); } return trim($content); } }

關鍵技術點解析

1. 正則表達式精準提取

  • 使用 sim 修飾符:s (單行模式讓 . 匹配換行)、i (忽略大小寫)、m (多行模式)。
  • 列表頁連結、標題、來源、內容區塊均針對目標站點 HTML 結構定製,需配合瀏覽器開發者工具調試。

2. 圖片本地化流程

  1. 從內容 HTML 提取所有 <IMG src="..."> 連結。
  2. 過濾相對路徑/非 HTTP 連結。
  3. file_get_contents 下載二進制內容。
  4. 取 URL 最後路徑段作為檔名(strrchr($url, '/'))。
  5. file_put_contents 寫入 ./static/uploads/news/ 目錄(需可寫權限)。
  6. str_replace 將內容中原始圖片 URL 替換為本地相對路徑。

3. 編碼轉換處理

目標站點為 GBK 編碼,CI 內部通常用 UTF-8,iconv("GBK", "UTF-8", $output) 確保中文不亂碼。若 iconv 失敗可嘗試 mb_convert_encoding。

4. 錯誤容忍與效能

  • set_time_limit(0) 防止長時間爬取被截斷。
  • 單篇入庫失敗 continue 不中斷整體流程。
  • 建議加入 sleep(1) 或 Token Bucket 限流,避免對目標站點造成過大壓力。

資料庫模型建議


// application/models/News_model.php
class News_model extends CI_Model {
    public function add($data) {
        return $this->db->insert('news', $data);
    }
}

資料表結構:


CREATE TABLE `news` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `source` varchar(100) DEFAULT '',
  `contents` longtext,
  `picture` varchar(500) DEFAULT '',
  `style` tinyint(3) DEFAULT '0',
  `create_time` int(11) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

進階優化方向

  1. 併發爬取: 引入 GuzzleHttp\Pool 或 Swoole 協程並發請求詳情頁。
  2. 斷點續爬: 記錄已爬取 URL 的 MD5 或 ID,支援中斷恢復。
  3. 反爬應對: 隨機 User-Agent、代理 IP 池、Cookies 池、驗證碼識別。
  4. 通用化抽取: 結合 DOMDocument / QueryList / Symfony DomCrawler 替代脆弱正則。
  5. 單元測試: 對 curl_snatch、解析邏輯編寫 PHPUnit 測試。

總結

這個 CI 爬蟲範例展示了從列表分頁、詳情解析、圖片本地化到入庫的完整閉環。實際專案中,請務必遵守 robots.txt、控制爬取頻率、處理異常編碼,並優先考慮使用成熟爬蟲框架(如 Scrapy、Guzzle+DOMCrawler)提升穩定性與可維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved