用libcurl发起最简http get请求是c++标准方案:先调用curl_easy_init()获取句柄并校验非空,再设curlopt_url、curlopt_followlocation、curlopt_timeout和curlopt_writefunction回调捕获响应,最后curl_easy_perform()执行并清理。

用 libcurl 发起最简 HTTP GET 请求
标准 C++ 没有内置 HTTP 客户端,必须依赖第三方库;libcurl 是最成熟、跨平台、生产可用的选择。别碰 std::net(还没进标准),也别手写 socket——HTTP 协议细节多,重定向、gzip、证书校验、超时控制都容易出错。
基础流程就三步:初始化句柄、设置选项、执行请求。关键不是“能不能发”,而是“怎么设才不崩”:
-
curl_easy_init()后必须检查返回值是否为nullptr,尤其在嵌入式或资源紧张环境可能失败 - 必须显式设置
CURLOPT_URL和CURLOPT_FOLLOWLOCATION,否则 302 重定向会直接返回空响应 - 务必设置
CURLOPT_TIMEOUT(比如30L),否则 DNS 卡住或服务器无响应时线程永久阻塞 - 接收数据要用回调函数(
CURLOPT_WRITEFUNCTION),别指望自动存到字符串——C++ 字符串内存管理得自己管
示例片段(只抓 HTML 内容):
std::string response;
auto write_callback = [](void* ptr, size_t size, size_t nmemb, void* userp) -> size_t {
auto& buf = *static_cast<:string>(userp);
size_t real_size = size * nmemb;
buf.append(static_cast<char>(ptr), real_size);
return real_size;
};
<p>CURL* curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "<a href="https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635">https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635</a>");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
</p></char></:string>
HTTPS 抓取失败常见原因和绕过方式
很多新手一试 HTTPS 就卡在 CURLE_SSL_CONNECT_ERROR 或证书验证失败。这不是代码写错了,而是 libcurl 默认严格校验证书链,而你的系统可能没装 CA 证书包,或目标网站用了自签名/过期证书。
生产环境绝不能关校验,但调试时可临时跳过(仅限本地开发):
- 加
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L)关闭证书公钥校验 - 加
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L)关闭域名匹配检查 - 更安全的调试方式是手动指定 CA 路径:
CURLOPT_CAINFO指向ca-bundle.crt文件(Linux 常在/etc/ssl/certs/ca-certificates.crt)
注意:CURLOPT_SSL_VERIFYPEER 和 CURLOPT_SSL_VERIFYHOST 必须同时设为 0L 才生效,只设一个仍可能失败。
POST 请求传参和表单提交要点
GET 只要拼 URL,POST 需明确内容类型和编码方式。最常用的是 application/x-www-form-urlencoded(浏览器表单默认格式),别直接拼 raw JSON——服务端很可能收不到。
- 用
CURLOPT_POSTFIELDS传键值对字符串,如"user=admin&pass=123",libcurl会自动加Content-Type头 - 若需发 JSON,必须手动设置头:
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers),其中headers是struct curl_slist*,含"Content-Type: application/json" -
CURLOPT_POST必须设为1L,否则CURLOPT_POSTFIELDS不生效 - POST 后不能再设
CURLOPT_FOLLOWLOCATION(某些版本 libcurl 会静默忽略),重定向需手动处理
编码、中文乱码与响应体解析
抓回来的 response 是原始字节流,没做任何编码转换。网页声明的 charset(如 UTF-8、GBK)必须你自己解析 HTML meta 标签或 Content-Type header,再用对应编码解码。
- 先从
curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct)拿到响应头中的Content-Type,提取charset=xxx - 若没声明或声明为
gb2312/gbk,而你用 UTF-8 解析,必然乱码;C++ 标准库不带 GBK 转码,得靠iconv或第三方库(如utf8cpp) - 别依赖
std::string的.c_str()直接喂给 GUI 或文件——它只是字节拷贝,不是“已解码字符串” - 如果只是提取文本内容,建议用
htmlcxx或gumbo-parser解析 DOM,比正则可靠得多
最常被忽略的一点:libcurl 默认不自动解压 gzip 响应。遇到 Content-Encoding: gzip 却没设 CURLOPT_ACCEPT_ENCODING,你会收到一堆乱码字节——加一句 curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "") 就让 libcurl 自动处理。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











