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

C++ 爬蟲實戰:基於 libcurl 與 PCRE 解析大眾點評數據

     編輯:關於C++

技術棧

  • libcurl:HTTP 請求處理(偽裝 UA、Cookie、重定向)。
  • PCRE:Perl 兼容正則表達式,HTML 結構化提取。
  • C++11:std::string、RAII 資源管理。

核心模塊設計

1. 寫入回調(CURL_WRITEFUNCTION)

size_t onWriteData(void* buffer, size_t size, size_t nmemb, void* userp) {
    std::string* html = static_cast(userp);
    if (!html || !buffer) return 0;
    html->append(static_cast(buffer), size * nmemb);
    return size * nmemb;  // 必須返回實際處理字節數
}

2. 頁面獲取封裝

int getWeb(const std::string& url, std::string& result) {
    CURL* curl = curl_easy_init();
    if (!curl) return -1;

    std::string html;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &html);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0");  // 反爬蟲
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);        // 支持重定向
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);               // 超時保護

    CURLcode res = curl_easy_perform(curl);
    long http_code = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    curl_easy_cleanup(curl);

    if (res == CURLE_OK && http_code == 200) {
        result = std::move(html);
        return 200;
    }
    return http_code ? http_code : -1;
}

3. PCRE 正則提取

void parseListings(const std::string& html) {
    const char* pattern = "(
  • )"; // 目標列表項 pcre* re = pcre_compile(pattern, 0, &error, &erroffset, NULL); if (!re) { /* 錯誤處理 */ return; } int ovector[30]; const char* ptr = html.c_str(); int len = html.length(); while (true) { int rc = pcre_exec(re, NULL, ptr, len, 0, 0, ovector, 30); if (rc == PCRE_ERROR_NOMATCH) break; if (rc < 0) { /* 其他錯誤 */ break; } // 提取匹配子串 for (int i = 0; i < rc; i++) { int start = ovector[2*i]; int length = ovector[2*i+1] - start; std::string match(ptr + start, length); // 處理 match: 解析店名、評分、價格等 std::cout << "Match: " << match << std::endl; } // 移動指針繼續搜尋 ptr += ovector[1]; len -= ovector[1]; if (len <= 0) break; } pcre_free(re); }
  • 完整主流程

    int main() {
        std::string url = "https://www.dianping.com/search/category/212/10/g103";
        std::string html;
        if (getWeb(url, html) == 200) {
            parseListings(html);
        } else {
            std::cerr << "頁面獲取失敗" << std::endl;
        }
        return 0;
    }

    關鍵工程細節

    1. 編碼處理:大眾點評頁面通常為 UTF-8,PCRE 需編譯 PCRE_UTF8 標誌,或使用 iconv 轉換。
    2. 反爬蟲應對:
      - 偽裝 User-Agent、Referer
      - Cookie 池輪換
      - 請求頻率限制(sleep)
      - 無頭瀏覽器 繞過 JS 渲染
    3. 內存管理:pcre_compile/pcre_free 配對;curl_easy_init/curl_easy_cleanup 配對。
    4. 錯誤恢復:網絡超時重試、HTML 結構變更檢測、增量爬取去重。

    法律與道德邊界

    • 遵守 robots.txt 協議。
    • 僅提取公開數據,不繞過驗證碼/登錄。
    • 數據僅供個人學習/研究,商業用途需授權。

    結語

    libcurl + PCRE 是 C/C++ 輕量級爬蟲的經典組合。實戰中核心難點不在請求發送,而在於反爬蟲對抗、動態頁面渲染、結構化提取穩健性。建議進階學習:libcurl 多接口并發、gumbo-parser 樹形 HTML 解析、Selenium/Playwright 無頭瀏覽器自動化。

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