
Aloísio Vítor
Image Processing Expert

El web scraping es una poderosa técnica para extraer datos de sitios web, permitiendo la automatización de tareas como la recopilación de información de precios, el seguimiento de actualizaciones de contenido o la recopilación de grandes conjuntos de datos. Una de las bibliotecas más populares para realizar web scraping en C++ es libcurl, una biblioteca gratuita y de código abierto para transferencias de URL del lado cliente. Soporta múltiples protocolos como HTTP, HTTPS, FTP y más, lo que la convierte en una opción ideal para recuperar contenido web.
libcurl es una potente biblioteca C para realizar peticiones HTTP, que admite diversos protocolos como HTTP, HTTPS, FTP y muchos más. Es una herramienta flexible que se utiliza ampliamente en aplicaciones C++ para realizar peticiones web.
Características:
CURLM para gestionar múltiples peticiones a la vez.Antes de utilizar libcurl, debes:
curl/curl.h en tu código C++.Puedes instalar libcurl en Linux con:
sudo apt-get install libcurl4-openssl-dev
Aquí tienes cómo realizar una simple petición GET utilizando libcurl en C++:
#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;
}
Aquí tienes un ejemplo en el que obtenemos datos de una API e imprimimos los resultados:
#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;
}
Para enrutar tus peticiones a través de un servidor proxy con 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 puede gestionar cookies activando la opción COOKIEFILE:
#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;
}
Para enviar encabezados personalizados o realizar una petición POST con 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) {
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;
}
En este ejemplo, demostraremos cómo resolver ReCaptcha V3 utilizando CapSolver: con la biblioteca libcurl en C++. La API de CapSolver permite una fácil interacción con las tareas de ReCaptcha y la recuperación de soluciones.
Antes de empezar, asegúrate de que tienes los siguientes requisitos previos:
sudo apt-get install libcurl4-openssl-dev en Linux)."YourKey" en el código siguiente con tu clave real).
Aquí tienes una guía paso a paso para resolver ReCaptcha V3 utilizando CapSolver:
El primer paso es enviar una petición a la API de CapSolver para crear una tarea para resolver ReCaptcha. La tarea incluye detalles como la URL del sitio web, la clave del sitio (de la página de destino) y la acción específica de la página.
#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 payload for task creation
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;
}
Esta función envía una petición POST a la API de CapSolver con los detalles necesarios de la tarea y devuelve la respuesta, que incluirá un taskId.
Una vez que la tarea se ha creado, tendrás que consultar la API de CapSolver para obtener el resultado de la tarea, que contiene el token para evitar el desafío de 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 payload to get the task result
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;
}
Esta función comprueba repetidamente el estado de la tarea hasta que está lista, momento en el que devuelve la solución de ReCaptcha.
Finalmente, aquí tienes cómo puedes integrar ambas funciones en tu código principal:
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;
}
Este código:
Reclama tu Código Extra para las mejores soluciones de captcha en CapSolver: scrape. Después de canjearlo, obtendrás un 5% de bonificación adicional después de cada recarga, de forma ilimitada.

Con libcurl, puedes manejar fácilmente las peticiones HTTP en aplicaciones C++. Integrándolo con CapSolver, puedes resolver captchas como ReCaptcha V3 y utilizar el resultado en tus peticiones.
Descubre CapSolver, el principal solucionador de CAPTCHA sin código para la automatización de IA en 2026, para optimizar los flujos de trabajo y mejorar la recopilación de datos sin necesidad de programar. Aprende sobre sus características principales, beneficios y uso ético.

Guía completa sobre la infraestructura de resolución de CAPTCHA que impulsa los navegadores Agentic. Aprende por qué los CAPTCHA son el obstáculo principal para los agentes de IA y cómo CapSolver proporciona la solución esencial para la automatización web fluida.
