std::string、RAII 資源管理。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; // 必須返回實際處理字節數
}
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;
}
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;
}
PCRE_UTF8 標誌,或使用 iconv 轉換。User-Agent、Referersleep)pcre_compile/pcre_free 配對;curl_easy_init/curl_easy_cleanup 配對。robots.txt 協議。libcurl + PCRE 是 C/C++ 輕量級爬蟲的經典組合。實戰中核心難點不在請求發送,而在於反爬蟲對抗、動態頁面渲染、結構化提取穩健性。建議進階學習:libcurl 多接口并發、gumbo-parser 樹形 HTML 解析、Selenium/Playwright 無頭瀏覽器自動化。