
Anh Tuan
Data Science Expert
Publicado Feb 03, 2025
Actualizado Jan 23, 2025 · min de lectura
¡Tu guía amigable para raspar sitios web, manejar CAPTCHAs e incluso tomar capturas de pantalla!
C# no solo sirve para crear aplicaciones o juegos de Windows; ¡también es una potencia para el web scraping! Con bibliotecas como HtmlAgilityPack, Selenium y Puppeteer Sharp, puedes extraer datos, automatizar interacciones e incluso resolver CAPTCHAs (sí, de verdad). En este tutorial, usaremos https://www.scrapethissite.com/pages/ como nuestro campo de pruebas. ¡Vamos a sumergirnos!
Primero, crea una nueva aplicación de consola de C#. Luego, instala estos paquetes NuGet:
Install-Package HtmlAgilityPack # Para el análisis HTML
Install-Package Selenium.WebDriver # Para la automatización del navegador
Install-Package PuppeteerSharp # Para capturas de pantalla y raspado avanzado
Install-Package Capsolver.SDK # Para resolver CAPTCHAs
Vamos a raspar datos de países desde https://www.scrapethissite.com/pages/simple/.
using HtmlAgilityPack;
using System.Net;
var url = "https://www.scrapethissite.com/pages/simple/";
var client = new WebClient();
client.Headers.Add("User-Agent", "Mozilla/5.0"); // ¡Sé educado!
var html = client.DownloadString(url);
var doc = new HtmlDocument();
doc.LoadHtml(html);
var countries = doc.DocumentNode.SelectNodes("//div[@class='country']");
foreach (var country in countries)
{
var name = country.SelectSingleNode(".//h3").InnerText.Trim();
var capital = country.SelectSingleNode(".//span[@class='country-capital']").InnerText.Trim();
Console.WriteLine($"País: {name}, Capital: {capital}");
}
Esto imprime todos los países y sus capitales. Sencillo, ¿verdad?
Algunas páginas necesitan un navegador real. Vamos a raspar la página de ejemplo AJAX usando Selenium:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
var options = new ChromeOptions();
options.AddArgument("--headless"); // Ejecutar en segundo plano
using var driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.scrapethissite.com/pages/ajax-javascript/");
var dynamicContent = driver.FindElement(By.CssSelector(".ajax-content")).Text;
Console.WriteLine($"Contenido AJAX: {dynamicContent}");
¿Tienes un CAPTCHA bloqueándote el camino? Usa Capsolver para evitar ReCaptchaV2. Así es como:
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;
using System.Text.Json;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Threading;
namespace CapSolverSeleniumExample
{
class Program
{
static async Task Main(string[] args)
{
string token = await GetCaptchaToken();
using var driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://www.example.com");
Thread.Sleep(5000);
driver.ExecuteScript("document.getElementById('g-recaptcha-response').innerHTML = arguments[0];", token);
var submitButton = driver.FindElement(By.Id("submit-button"));
submitButton.Click();
Thread.Sleep(5000);
driver.Quit();
}
static async Task<string> GetCaptchaToken()
{
string apiKey = "YOUR_API_KEY";
string siteKey = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_kl-";
string siteUrl = "https://www.example.com";
using var client = new HttpClient();
var payload = new
{
clientKey = apiKey,
task = new
{
type = "ReCaptchaV3TaskProxyLess",
websiteKey = siteKey,
websiteURL = siteUrl,
pageAction = "login"
}
};
var requestContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var createTaskResponse = await client.PostAsync("https://api.capsolver.com/createTask", requestContent);
var createTaskResponseString = await createTaskResponse.Content.ReadAsStringAsync();
using var createTaskJsonDoc = JsonDocument.Parse(createTaskResponseString);
var root = createTaskJsonDoc.RootElement;
if (!root.TryGetProperty("taskId", out var taskIdElement))
{
Console.WriteLine("Error al crear la tarea: " + createTaskResponseString);
return null;
}
int taskId = taskIdElement.GetInt32();
while (true)
{
await Task.Delay(1000);
var resultPayload = new { clientKey = apiKey, taskId = taskId };
var resultContent = new StringContent(JsonSerializer.Serialize(resultPayload), Encoding.UTF8, "application/json");
var getTaskResponse = await client.PostAsync("https://api.capsolver.com/getTaskResult", resultContent);
var getTaskResponseString = await getTaskResponse.Content.ReadAsStringAsync();
using var getTaskJsonDoc = JsonDocument.Parse(getTaskResponseString);
var resultRoot = getTaskJsonDoc.RootElement;
if (resultRoot.TryGetProperty("status", out var statusElement))
{
string status = statusElement.GetString();
if (status == "ready")
{
if (resultRoot.TryGetProperty("solution", out var solutionElement) && solutionElement.TryGetProperty("gRecaptchaResponse", out var tokenElement))
{
return tokenElement.GetString();
}
return null;
}
if (status == "failed" || resultRoot.TryGetProperty("errorId", out _))
{
Console.WriteLine("¡Solución fallida! respuesta: " + getTaskResponseString);
return null;
}
}
}
}
}
}
Funciona perfectamente con Selenium para automatizar formularios con muchos CAPTCHAs!
¿Quieres una prueba visual de tu raspado? Captura una captura de pantalla:
using PuppeteerSharp;
await new BrowserFetcher().DownloadAsync();
using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
using var page = await browser.NewPageAsync();
await page.GoToAsync("https://www.scrapethissite.com/pages/javascript/");
await page.ScreenshotAsync("screenshot.png");
Perfecto para depurar o archivar páginas.
Thread.Sleep(2000) para evitar sobrecargar los servidores.try-catch para problemas de red.
Anh Tuan
Data Science Expert
Turning task outcomes into actionable insights.
SOBRE EL AUTOR
Solucionar problemas de solicitudes lentas de la API CAPTCHA con comprobaciones claras de la creación de tareas, el sondeo de resultados, los errores, la caducidad del token y la acción final del navegador después de resolverla.

Elija un solucionador de CAPTCHA para el monitoreo de productos al verificar la cobertura de desafíos, las observaciones completas de productos, el esfuerzo de integración, el costo de operación y el soporte.
