网页抓取是一种从网站提取数据的强大技术,它可以自动化诸如收集定价信息、监控内容更新或收集大型数据集等任务。libcurl 是 C++ 中最流行的网页抓取库之一,它是一个免费且开源的客户端 URL 传输库。它支持多种协议,如 HTTP、HTTPS、FTP 等,使其成为检索网络内容的理想选择。
libcurl 简介
libcurl 是一个强大的 C 库,用于发出 HTTP 请求,支持多种协议,如 HTTP、HTTPS、FTP 等等。它是一个灵活的工具,广泛应用于 C++ 应用程序中执行网络请求。
特性:
- 多协议支持: HTTP、HTTPS、FTP、FTPS、SMTP 等。
- 异步支持: 通过
CURLM
一次管理多个请求。 - 错误处理: 提供详细的错误消息和状态代码。
- 身份验证: 支持基本、摘要、NTLM、协商等。
- Cookie 和会话: 可以轻松管理 Cookie 和会话信息。
先决条件
在使用 libcurl 之前,您必须:
- 在您的系统上安装 libcurl。
- 在您的 C++ 代码中包含
curl/curl.h
头文件。
您可以在 Linux 上使用以下命令安装 libcurl:
sudo apt-get install libcurl4-openssl-dev
基本示例:发出 GET 请求
以下是如何使用 C++ 中的 libcurl 执行简单的 GET 请求:
#include <iostream>
#include <curl/curl.h>
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "Response: " << readBuffer << std::endl;
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
网页抓取示例:从 API 获取 JSON 数据
以下是一个从 API 获取数据并打印结果的示例:
#include <iostream>
#include <curl/curl.h>
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://jsonplaceholder.typicode.com/posts");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "Response: " << readBuffer << std::endl;
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
使用 libcurl 处理代理
要通过 libcurl 将您的请求路由到代理服务器:
#include <iostream>
#include <curl/curl.h>
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/ip");
curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxyserver:8080");
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "username:password");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "Response: " << readBuffer << std::endl;
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
使用 libcurl 处理 Cookie
libcurl 可以通过启用 COOKIEFILE
选项来管理 Cookie:
#include <iostream>
#include <curl/curl.h>
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/cookies/set?name=value");
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "Response: " << readBuffer << std::endl;
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
高级用法:自定义标头和 POST 请求
要发送自定义标头或执行 libcurl 的 POST 请求:
#include <iostream>
#include <curl/curl.h>
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "User-Agent: Mozilla/5.0");
headers = curl_slist_append(headers, "Accept-Language: en-US,en;q=0.5");
curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "username=testuser&password=testpass");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "Response: " << readBuffer << std::endl;
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
示例:使用 CapSolver 和 libcurl (C++) 解决 ReCaptcha V3
在本示例中,我们将演示如何使用 C++ 中的 CapSolver: 和 libcurl 库解决 ReCaptcha V3。CapSolver API 允许轻松与 ReCaptcha 任务进行交互并检索解决方案。
在开始之前,确保您具备以下先决条件:
- 在您的系统上安装 libcurl(在 Linux 上通过
sudo apt-get install libcurl4-openssl-dev
安装它)。 - CapSolver API 密钥(将代码中的
"YourKey"
替换为您的实际密钥)。
以下是使用 CapSolver 解决 ReCaptcha V3 的分步指南:
第 1 步:创建任务
第一步是向 CapSolver 的 API 发送请求以创建解决 ReCaptcha 的任务。该任务包含网站 URL、网站密钥(来自目标页面)和特定页面操作等详细信息。
#include <iostream>
#include <string>
#include <curl/curl.h>
#include <json/json.h>
const std::string CAPSOLVER_KEY = "YourKey";
const std::string PAGE_URL = "https://antcpt.com/score_detector";
const std::string PAGE_KEY = "6LcR_okUAAAAAPYrPe-HK_0RULO1aZM15ENyM-Mf";
const std::string PAGE_ACTION = "homepage";
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
std::string createTask(const std::string& url, const std::string& key, const std::string& action) {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://api.capsolver.com/createTask");
curl_easy_setopt(curl, CURLOPT_POST, 1L);
// JSON 负载用于任务创建
Json::Value payload;
payload["clientKey"] = CAPSOLVER_KEY;
payload["task"]["type"] = "ReCaptchaV3TaskProxyLess";
payload["task"]["websiteURL"] = url;
payload["task"]["websiteKey"] = key;
payload["task"]["pageAction"] = action;
Json::StreamWriterBuilder writer;
std::string requestData = Json::writeString(writer, payload);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestData.c_str());
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return readBuffer;
}
此函数向 CapSolver API 发送一个 POST 请求,其中包含必要的任务详细信息,并返回响应,其中将包含一个 taskId
。
第 2 步:检索 CAPTCHA 解决方案
创建任务后,您需要查询 CapSolver 的 API 以获取任务的结果,其中包含用于绕过 ReCaptcha 挑战的令牌。
std::string getTaskResult(const std::string& taskId) {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://api.capsolver.com/getTaskResult");
curl_easy_setopt(curl, CURLOPT_POST, 1L);
// JSON 负载用于获取任务结果
Json::Value payload;
payload["clientKey"] = CAPSOLVER_KEY;
payload["taskId"] = taskId;
Json::StreamWriterBuilder writer;
std::string requestData = Json::writeString(writer, payload);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestData.c_str());
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
do {
readBuffer.clear();
res = curl_easy_perform(curl);
std::this_thread::sleep_for(std::chrono::seconds(5));
} while (readBuffer.find("\"status\":\"ready\"") == std::string::npos);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return readBuffer;
}
此函数会重复检查任务状态,直到任务准备就绪,然后返回 ReCaptcha 解决方案。
第 3 步:整合在一起
最后,以下是如何将这两个函数整合到您的主代码中:
int main() {
std::cout << "Creating CAPTCHA task..." << std::endl;
std::string taskResponse = createTask(PAGE_URL, PAGE_KEY, PAGE_ACTION);
Json::CharReaderBuilder reader;
Json::Value jsonResponse;
std::string errors;
std::istringstream taskStream(taskResponse);
std::string taskId;
if (Json::parseFromStream(reader, taskStream, &jsonResponse, &errors)) {
taskId = jsonResponse["taskId"].asString();
std::cout << "Task ID: " << taskId << std::endl;
std::cout << "Retrieving CAPTCHA result..." << std::endl;
std::string resultResponse = getTaskResult(taskId);
Json::Value resultJson;
std::istringstream resultStream(resultResponse);
Json::parseFromStream(reader, resultStream, &resultJson, &errors);
std::string token = resultJson["solution"]["gRecaptchaResponse"].asString();
std::cout << "Token Solution: " << token << std::endl;
} else {
std::cerr << "Error parsing task response: " << errors << std::endl;
}
return 0;
}
这段代码将:
- 通过 CapSolver 创建一个 ReCaptcha 任务。
- 等待任务完成。
- 检索 ReCaptcha 令牌解决方案并将其打印出来。
附加代码
在 CapSolver: 上获取顶级验证码解决方案的 附加代码:scrape。兑换后,每次充值后,您将获得额外的 5% 奖励,无限次。
结论
借助 libcurl,您可以在 C++ 应用程序中轻松处理 HTTP 请求。通过将其与 CapSolver 集成,您可以解决诸如 ReCaptcha V3 之类的验证码,并在您的请求中使用结果。
CapsolverCN官 方代理交流扣 群:497493756