ProductsIntegrationsResourcesDocumentationPricing
Start Now

© 2026 CapSolver. All rights reserved.

CONTACT US

Slack: lola@capsolver.com

Products

  • reCAPTCHA v2
  • reCAPTCHA v3
  • Cloudflare Turnstile
  • Cloudflare Challenge
  • AWS WAF
  • Browser Extension
  • Many more CAPTCHA types

Integrations

  • Selenium
  • Playwright
  • Puppeteer
  • n8n
  • Partners
  • View All Integrations

Resources

  • Referral System
  • Documentation
  • API Reference
  • Blog
  • FAQs
  • Glossary
  • Status

Legal

  • Terms & Conditions
  • Privacy Policy
  • Refund Policy
  • Don't Sell My Info
Blog/All/Web Scraping in C#: Step-by-Step Tutorial in 2026
Feb03, 2025

Web Scraping in C#: Step-by-Step Tutorial in 2026

Lucas Mitchell

Lucas Mitchell

Automation Engineer

Your friendly guide to scraping websites, handling CAPTCHAs, and even taking screenshots!


Why Web Scraping in C#?

C# isn’t just for building Windows apps or games—it’s a powerhouse for web scraping too! With libraries like HtmlAgilityPack, Selenium, and Puppeteer Sharp, you can extract data, automate interactions, and even solve CAPTCHAs (yes, really). In this tutorial, we’ll use https://www.scrapethissite.com/pages/ as our playground. Let’s dive in!


Step 1: Setting Up Your Project

First, create a new C# console app. Then, install these NuGet packages:

bash Copy
Install-Package HtmlAgilityPack        # For HTML parsing
Install-Package Selenium.WebDriver     # For browser automation
Install-Package PuppeteerSharp         # For screenshots & advanced scraping
Install-Package Capsolver.SDK          # For CAPTCHA solving

Example 1: Basic Page Scraping

Let’s scrape country data from https://www.scrapethissite.com/pages/simple/.

csharp Copy
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"); // Be polite!
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($"Country: {name}, Capital: {capital}");
}

This prints all countries and their capitals. Simple, right?


Example 2: Handling JavaScript with Selenium

Some pages need a real browser. Let’s scrape the AJAX example page using Selenium:

csharp Copy
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

var options = new ChromeOptions();
options.AddArgument("--headless"); // Run in background
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($"AJAX Content: {dynamicContent}");

Example 3: Solving CAPTCHAs with CapSolver

Got a CAPTCHA blocking your way? Use CapSolver to bypass ReCaptchaV2. Here’s how:

  1. Sign up for CapSolver, grab your API key.
  2. Use the API to solve a CAPTCHA:
csharp Copy
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("Failed to create task: " + 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("Solve failed! response: " + getTaskResponseString);
                        return null;
                    }
                }
            }
        }
    }
}

Works seamlessly with Selenium to automate CAPTCHA-heavy forms!


Example 4: Taking Screenshots with Puppeteer Sharp

Want visual proof of your scraping? Capture a screenshot:

csharp Copy
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");

Perfect for debugging or archiving pages.


Pro Tips for 2026 Web Scraping

  1. Respect robots.txt: Check https://www.scrapethissite.com/robots.txt first.
  2. Rate limiting: Add delays with Thread.Sleep(2000) to avoid overwhelming servers.
  3. User-Agent rotation: Mimic real browsers to avoid detection.
  4. Error handling: Wrap code in try-catch blocks for network issues.

More

AIApr 22, 2026

Best AI for Solving Image Puzzles: Top Tools and Strategies for 2026

Discover the best AI for solving image puzzles. Learn how CapSolver's Vision Engine and ImageToText APIs automate complex visual challenges with high accuracy.

Ethan Collins
Ethan Collins
web scrapingApr 22, 2026

Rust Web Scraping Architecture for Scalable Data Extraction

Learn scalable Rust web scraping architecture with reqwest, scraper, async scraping, headless browser scraping, proxy rotation, and compliant CAPTCHA handling.

Contents

Lucas Mitchell
Lucas Mitchell
AIApr 22, 2026

Search API vs Knowledge Supply Chain: AI Data Infrastructure Guide

Learn how search API tools, knowledge supply chains, SERP API workflows, and AI data pipelines shape modern web data infrastructure for AI.

Anh Tuan
Anh Tuan
about-capsolverApr 20, 2026

The Evolution of Automation Infrastructure: How CapSolver's Strategic Upgrade Empowers Data-Driven Businesses

CapSolver evolves into a core automation layer with improved UI, integrations, and enterprise-grade data capabilities.

Lucas Mitchell
Lucas Mitchell