In a separate article we looked at which language to write a scraper in and compared the languages head to head. This is the next level of detail: a catalog of specific libraries. Once the language is chosen, you still have to pick the tools — so here's the roundup, broken out by language and role, with links to the official sites. The best Python web scraping libraries lead the list, followed by top picks for the other major languages.
The four roles a library plays
Before naming specific packages, it helps to understand that almost any scraper is assembled from tools of four types. Often a single library isn't used on its own but in combination: an HTTP client fetches the HTML, and a parser picks it apart.
- HTTP clients. Send requests and receive the response (HTML, JSON). Fast and lightweight, but they don't execute JavaScript — they see only what the server returned. Good for static pages and for hitting a site's API directly.
- HTML/XML parsers. Turn an HTML string into a tree you can query with CSS selectors or XPath. They don't fetch anything themselves — you feed them ready HTML.
- Browser automation (headless). Launch a real browser (usually Chromium), execute JavaScript, and can click, scroll, fill forms and wait for elements to appear. Indispensable for single-page apps and dynamic content, but heavy on resources.
- Full frameworks. Take over the whole pipeline: request queue, concurrency, retries, processing and storing data. Suited to large, recurring jobs where you care about thousands of pages, not one.
Below are the libraries by language, grouped internally by these roles.
Python
HTTP clients: requests — the classic, synchronous and simple; httpx — a modern replacement with async and HTTP/2 support; aiohttp — an async client for high load; curl_cffi — spoofs the TLS fingerprint to match a real Chrome, helping you clear basic anti-bot defenses without a browser.
Parsers: BeautifulSoup — the friendliest for beginners; lxml — fast, C-based, with XPath support; parsel — the selector engine from the Scrapy ecosystem; selectolax — the fastest at large volumes; pyquery — jQuery-style syntax.
Browser automation: Playwright — the modern default (async, auto-waiting); Selenium — the veteran, with a huge community; SeleniumBase — a layer over Selenium with a stealth mode; nodriver — a stealth tool from the author of undetected-chromedriver (the latter is now largely dated and clears modern defenses less reliably).
Frameworks: Scrapy — the mature standard for large crawls with pipelines; Crawlee for Python — a hybrid that switches between HTTP and browser; MechanicalSoup — lightweight form and session handling; Scrapling — a newer adaptive parser that's resilient to markup changes.
JavaScript / Node.js
HTTP clients: the native fetch; axios — the most popular client with a convenient API; got — light and fast; undici — a high-performance client from the Node.js team.
Parsers: cheerio — fast static-HTML parsing in a jQuery style; jsdom — a full DOM emulation (heavier than cheerio); parse5 and htmlparser2 — low-level parsers that other tools are built on.
Browser automation: Puppeteer — Chrome/Chromium control; Playwright — the same with multi-browser support and a clean API; puppeteer-extra — plugins, including stealth for evasion.
Frameworks: Crawlee — a powerful framework from Apify with queues, proxies and auto-switching between HTTP and browser; node-crawler — a classic crawler with a request pool.
PHP
HTTP clients: Guzzle — the de facto standard, PSR-compatible; Symfony HttpClient — a modern client from the Symfony ecosystem; native cURL.
Parsers: Symfony DomCrawler — parsing by CSS selectors and XPath; DiDOM — fast and simple; Simple HTML DOM — the lowest barrier to entry, digests "broken" HTML.
Navigation and browser: Symfony BrowserKit (the HttpBrowser class) — a pure-PHP browser emulation that follows links and submits forms but doesn't execute JS (the deprecated Goutte migrated here); Symfony Panther and php-webdriver — control a real Chrome/Firefox for dynamic content; chrome-php — control Chrome directly.
Frameworks: Roach PHP — a full Scrapy analog for PHP with pipelines and middleware; crwlr — a framework of ready-made "step" blocks for crawlers.
Go (Golang)
HTTP clients: net/http — a powerful standard library; resty — a convenient wrapper with a concise API.
Parsers: goquery — jQuery-style parsing (CSS selectors); htmlquery — selection by XPath.
Browser automation: chromedp — the industry standard, driving Chrome over the DevTools Protocol; Rod — a modern alternative with a friendly API; playwright-go — a Playwright port.
Frameworks: Colly — a fast concurrent framework for static content; Geziyor — a framework with JS-rendering support; Ferret — data extraction via its own declarative query language.
C / C++
There are almost no high-level frameworks in this niche — people assemble an "HTTP client + parser" pairing by hand, for maximum speed and minimal memory use.
HTTP clients: libcurl — the foundational library that clients in most languages rest on; CPR — a modern C++ wrapper over libcurl in the style of Python requests.
Parsers: libxml2 — a mature HTML/XML parser; Gumbo — an HTML5 parser from Google; lexbor — a fast, modern HTML/CSS engine; pugixml — a lightweight XML parser for sitemaps and RSS.
There's no JavaScript execution out of the box — when you need it, you integrate an embedded browser engine or an external headless one.
C# / .NET
HTTP clients: HttpClient — the built-in .NET client; RestSharp — a convenient wrapper for REST requests.
Parsers: HtmlAgilityPack — the most popular, tolerates "broken" HTML, supports XPath; AngleSharp — W3C-compliant, with a browser-like querySelector; Fizzler — a CSS-selector engine on top of HtmlAgilityPack.
Browser automation: PuppeteerSharp — a Puppeteer port; Playwright for .NET — the official Playwright port; Selenium WebDriver.
Frameworks: DotnetSpider — a Scrapy-style framework; Abot — a configurable crawler.
Java
HTTP clients: Apache HttpClient — the mature standard; OkHttp — a modern, fast client.
Parsers: Jsoup — the main HTML-parsing tool in Java, with convenient CSS selectors.
Browser automation: HtmlUnit — a headless browser in pure Java with partial JS support; Selenium and Playwright for Java — real-browser control.
Frameworks: WebMagic — a Scrapy-style framework; Crawler4j — a simple, fast crawler.
Ruby
HTTP clients: Faraday — a flexible client with middleware; HTTParty — concise and simple.
Parsers: Nokogiri — the standard for HTML/XML parsing in Ruby (CSS and XPath).
Browser automation: Ferrum — Chrome control over CDP; Watir and Selenium — a real browser.
Navigation and frameworks: Mechanize — follows links and handles forms (no JS); Kimurai — a Scrapy-style framework with headless-engine support.
Rust
HTTP clients: reqwest — the main async client; ureq — a simple synchronous one.
Parsers: scraper — CSS selectors, similar in spirit to BeautifulSoup/Cheerio; select — an alternative selector-based parser.
Browser automation: fantoccini and thirtyfour — browser control over WebDriver; headless_chrome and chromiumoxide — working with Chrome over the DevTools Protocol.
Frameworks: spider — a high-performance concurrent crawler.
Library comparison table
| Library | Language | Type | Executes JS | Async / concurrency | What stands out |
|---|---|---|---|---|---|
| requests | Python | HTTP client | No | No | The benchmark for simplicity |
| httpx | Python | HTTP client | No | Yes | Async + HTTP/2 |
| curl_cffi | Python | HTTP client | No | Yes | TLS-fingerprint spoofing |
| BeautifulSoup | Python | Parser | — | — | Low barrier to entry |
| selectolax | Python | Parser | — | — | Fastest at scale |
| Playwright | Python | Browser | Yes | Yes | Auto-waiting, multi-browser |
| Selenium | many languages | Browser | Yes | Partial | Veteran, huge community |
| Scrapy | Python | Framework | No* | Yes | Standard for large crawls |
| cheerio | JS / Node | Parser | — | — | Fast jQuery-style static parsing |
| Puppeteer | JS / Node | Browser | Yes | Yes | Native Chrome control |
| Playwright | JS / Node | Browser | Yes | Yes | Multi-browser, clean API |
| Crawlee | JS / Node | Framework | Yes | Yes | Auto HTTP/browser switching |
| Guzzle | PHP | HTTP client | No | Yes | The de facto standard in PHP |
| Symfony DomCrawler | PHP | Parser | — | — | CSS selectors and XPath |
| Symfony Panther | PHP | Browser | Yes | No | A real browser for PHP |
| Roach PHP | PHP | Framework | No* | Yes | Scrapy analog for PHP |
| Colly | Go | Framework | No | Yes | Fast concurrent crawling |
| goquery | Go | Parser | — | — | jQuery syntax |
| chromedp | Go | Browser | Yes | Yes | The standard for dynamic content in Go |
| Rod | Go | Browser | Yes | Yes | Modern API |
| libcurl | C / C++ | HTTP client | No | Yes | The foundation across languages |
| lexbor | C / C++ | Parser | — | — | Fast HTML/CSS engine |
| HtmlAgilityPack | C# | Parser | — | — | Tolerates "broken" HTML |
| AngleSharp | C# | Parser | — | — | W3C-compliant, querySelector |
| PuppeteerSharp | C# | Browser | Yes | Yes | Puppeteer for .NET |
| Jsoup | Java | Parser | — | — | The main parser in Java |
| HtmlUnit | Java | Browser | Partial | Yes | Headless browser in pure Java |
| WebMagic | Java | Framework | No | Yes | Scrapy-style for Java |
| Nokogiri | Ruby | Parser | — | — | The parsing standard in Ruby |
| Ferrum | Ruby | Browser | Yes | Yes | Chrome control over CDP |
| Kimurai | Ruby | Framework | Yes | Yes | Scrapy-style for Ruby |
| reqwest | Rust | HTTP client | No | Yes | The main async client |
| scraper | Rust | Parser | — | — | CSS selectors |
| thirtyfour | Rust | Browser | Yes | Yes | Control over WebDriver |
| spider | Rust | Framework | Yes | Yes | High performance |
* The Scrapy and Roach PHP frameworks execute only static HTML on their own, but JS rendering plugs in via an add-on (Scrapy through scrapy-playwright, Roach through Browsershot). A "—" in a column means the criterion doesn't apply to that library type.
How to assemble a working stack
The short logic for picking tools to fit the job:
- A static page or a direct API call — an HTTP client and a parser are enough: for example requests + BeautifulSoup, Guzzle + DomCrawler, or net/http + goquery.
- Content loaded via JavaScript, with clicks and scrolling needed — reach for browser automation: Playwright, Puppeteer, chromedp.
- Thousands of pages, a recurring run, processing and storing data — you need a framework: Scrapy, Crawlee, Colly, Roach PHP.
- A site that actively blocks bots — add a separate layer: TLS-fingerprint spoofing (curl_cffi), stealth modes (nodriver, puppeteer-extra), and rotating proxies. This works on top of any library above and doesn't depend on the language you chose.
Choosing tools is the easy part; keeping a large scrape running reliably against anti-bot defenses, proxies and shifting markup is where projects stall. If you'd rather have the data than maintain the stack, scraping.pro runs this as a managed data-as-a-service offering. Otherwise, in the next articles we'll put specific libraries to work on practical examples — with data extraction, pagination and block avoidance.