Scrapling 是一个 Python 网页抓取框架,把快速 HTTP 请求、隐身浏览器、JavaScript 渲染、元素解析和并发爬虫整合到同一套接口中。它既能抓取静态页面,也能模拟浏览器交互并捕获后台 API 数据;支持 CSS、XPath、文本和正则提取,还能输出整洁 Markdown。面向规模化采集时,它提供可复用会话、代理轮换、自动重试、限速、暂停续爬以及 JSON、CSV 等格式导出,并可通过 Python、命令行或 MCP 服务供 AI 代理调用。
[](https://trendshift.io/repositories/14244)
[](https://www.star-history.com/d4vinci/scrapling)
[](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_AR.md)
[](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_ES.md)
[-DFE0E5 "os:x|center")](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_PT_BR.md)
[](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_FR.md)
[](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_DE.md)
[](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_CN.md)
[](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_JP.md)
[](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_RU.md)
[](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_KR.md)
[](https://github.com/D4Vinci/Scrapling/actions/workflows/tests.yml)
[](https://badge.fury.io/py/Scrapling)
[](https://hub.docker.com/r/pyd4vinci/scrapling)
[](https://clickpy.clickhouse.com/dashboard/scrapling)
[](https://scrapling.readthedocs.io/en/latest/ai/agent-skill.html)
[](https://clawhub.ai/D4Vinci/scrapling-official)
[](https://discord.gg/EMgGbDceNQ)
[](https://x.com/Scrapling_dev)
[](https://pypi.org/project/scrapling/)
[Selection methods](https://scrapling.readthedocs.io/en/latest/parsing/selection.html)
·
[Fetchers](https://scrapling.readthedocs.io/en/latest/fetching/choosing.html)
·
[Spiders](https://scrapling.readthedocs.io/en/latest/spiders/architecture.html)
·
[Proxy Rotation](https://scrapling.readthedocs.io/en/latest/spiders/proxy-blocking.html)
·
[CLI](https://scrapling.readthedocs.io/en/latest/cli/overview.html)
·
[MCP](https://scrapling.readthedocs.io/en/latest/ai/mcp-server.html)
Scrapling is a Python Web Scraping framework that brings fast HTTP requests, stealth browsers, powerful parsing, and concurrent crawling into one library.
Scrape static pages, render JavaScript, interact with websites, and extract data from the API calls behind them. Build crawlers with reusable sessions, proxy rotation, automatic retries, pause/resume, and built-in data exports.
Use it from Python, the terminal, or your AI agent through its MCP server and Agent Skill. From extracting a few fields to collecting a whole website as clean Markdown, Scrapling covers the full scraping workflow.
Start with a single page:
from scrapling.fetchers import Fetcher
page = Fetcher.get('https://quotes.toscrape.com/')
quotes = page.css('.quote .text::text').getall()
print(quotes)
Or scale up with a spider:
from scrapling.spiders import Spider, Response
class QuotesSpider(Spider):
name = "quotes"
start_urls = ["https://quotes.toscrape.com/"]
async def parse(self, response: Response):
for quote in response.css('.quote'):
yield {
"text": quote.css('.text::text').get(),
"author": quote.css('.author::text').get(),
}
result = QuotesSpider().start()
print(len(result.items))
result.items.to_json("quotes.json")
This prints 10 and saves the quotes and authors to quotes.json.
[](https://dataimpulse.com/?utm_source=scrapling&utm_medium=banner&utm_campaign=scrapling)
[](https://go.nodemaven.com/scraplingseptember)
[NodeMaven](https://go.nodemaven.com/scraplingseptember) - The most efficient proxy provider for Web Scraping and Automation with the Highest Quality IP on the market. Use code SCRAPLING35 for 35% discount.
[](https://hypersolutions.co/?utm_source=github&utm_medium=readme&utm_campaign=scrapling)
Scrapling handles Cloudflare Turnstile. For enterprise-grade protection, Hyper Solutions provides API endpoints that generate valid antibot tokens for Akamai, DataDome, Kasada, and Incapsula. Simple API calls, no browser automation required.
[](https://evomi.com?utm_source=github&utm_medium=banner&utm_campaign=d4vinci-scrapling)
[Evomi](https://evomi.com?utm_source=github&utm_medium=banner&utm_campaign=d4vinci-scrapling): residential proxies from $0.49/GB. Scraping browser with fully spoofed Chromium, residential IPs, auto CAPTCHA solving, and anti-bot bypass.
Scraper API for hassle-free results. MCP and N8N integrations are available.
[](https://tikhub.io/?utm_source=github.com/D4Vinci/Scrapling&utm_medium=marketing_social&utm_campaign=retargeting&utm_content=carousel_ad)
[TikHub.io](https://tikhub.io/?utm_source=github.com/D4Vinci/Scrapling&utm_medium=marketing_social&utm_campaign=retargeting&utm_content=carousel_ad) provides 900+ stable APIs across 16+ platforms including TikTok, X, YouTube & Instagram, with 40M+ datasets.
Also offers DISCOUNTED AI models - Claude, GPT, GEMINI & more up to 71% off.
[](https://substack.thewebscraping.club/p/scrapling-hands-on-guide?utm_source=github&utm_medium=repo&utm_campaign=scrapling)
Read a full review of [Scrapling on The Web Scraping Club](https://substack.thewebscraping.club/p/scrapling-hands-on-guide?utm_source=github&utm_medium=repo&utm_campaign=scrapling) (Nov 2025), the #1 newsletter dedicated to Web Scraping.
[](https://www.swiftproxy.net/?ref=D4Vinci)
[Swiftproxy](https://www.swiftproxy.net/?ref=D4Vinci) provides scalable residential proxies with 80M+ IPs across 195+ countries, delivering fast, reliable connections, automatic rotation, and strong anti-block performance. Free trial available.
[](https://byteful.com/?utm_source=github&utm_medium=github-sponsor&utm_campaign=scrapling_github_sponsor)
[Byteful](https://byteful.com/?utm_source=github&utm_medium=github-sponsor&utm_campaign=scrapling_github_sponsor) supplies ethical residential, mobile, ISP, and datacenter proxies, plus scraping and AI automation tools. Use code SCRAPLING10: 10% off residential proxies.
[](https://proxylane.dev/?utm_source=scrapling&utm_medium=partnership&utm_campaign=scrapling_platinum_202609&utm_content=github_readme)
[ProxyLane](https://proxylane.dev/?utm_source=scrapling&utm_medium=partnership&utm_campaign=scrapling_platinum_202609&utm_content=github_readme): Reduce blocks and CAPTCHAs by 90%. 28M Premium Residential IPs for Heavy Web Scraping. 195 countries. City/ISP/ZIP targeting. Sticky/rotating sessions. Non-expiring traffic from $2/GB. Code SCRAPEANDTAKE: 25% off.
[](https://www.lundproxy.com/unlimited-residential-bandwidth.html?utm_source=github&utm_medium=sponsorship&utm_campaign=scrapling&utm_content=banner)
[LundProxy](https://www.lundproxy.com?utm_source=github&utm_medium=sponsorship&utm_campaign=scrapling&utm_content=text): Stop paying per GB. Unlimited residential traffic, 100M+ IPs, 190+ countries. Pay by bandwidth. Request a free 50 Mbps residential proxies trial.
[](https://dataimpulse.com/?utm_source=website&utm_medium=github_readme&utm_campaign=scrapling_platinum)
$1/GB at [DataImpulse](https://dataimpulse.com/?utm_source=website&utm_medium=github_readme&utm_campaign=scrapling_platinum). Ethical first-party proxies. 90M+ IPs, 195+ countries. Residential, datacenter, mobile. Pay-as-you-go = no subscription. Traffic never expires.
Do you want to show your ad here? Click here
Do you want to show your ad here? Click here and choose the tier that suits you!
start_urls, async parse callbacks, and Request/Response objects.crawldir. Press Ctrl+C to stop gracefully and restart with the same directory.async for item in spider.stream() with real-time stats - ideal for UI, pipelines, and long-running crawls.Retry-After asks) whenever the website starts blocking or rate-limiting you, and speeds back up once it stops.robots_txt_obey flag that respects Disallow, Crawl-delay, and Request-rate directives with per-domain caching.parse() logic without re-hitting the target servers.CrawlSpider for rule-based link following, SitemapSpider for sitemap/robots.txt-driven crawls, XMLFeedSpider/CSVFeedSpider for iterating XML/RSS and CSV feeds, and ShopifySpider to collect products from public Shopify stores, one item per variant.LinkExtractor primitive with allow/deny patterns, domain filters, CSS/XPath scoping, extension filtering, and canonicalization - use it inside the templates or on its own.result.items.to_json(), to_jsonl(), to_csv(), and to_xml().Fetcher class. Can impersonate browsers' TLS fingerprint, headers, and use HTTP/3.StealthyFetcher class supporting Playwright's Chromium and Google's Chrome.StealthyFetcher and fingerprint spoofing. Can easily bypass all types of Cloudflare's Turnstile/Interstitial with automation.FetcherSession and StealthySession classes for cookie and state management across requests.ProxyRotator with cyclic or custom rotation strategies across all session types, plus per-request proxy overrides.cdp_url, whether it's on the same machine, another host, or a managed browser provider. You can also point any browser fetcher at your own Chromium build with executable_path.record_requests=True on a browser session, then search its saved responses with session.network.search(limit=None). Read API data and HTTP errors across page loads without sending requests again. History is bounded and saves text response bodies.page.markdown()), or crawl a whole website into a Markdown corpus with the ContentSpider template, all without an LLM in the loop. (docs)scrapling_response to parse the responses you already fetch with Scrapling's parser, no rewrite needed.Let's give you a quick glimpse of what Scrapling can do without deep diving.
HTTP requests with session support
from scrapling.fetchers import Fetcher, FetcherSession
with FetcherSession(impersonate='chrome') as session: # Use latest version of Chrome's TLS fingerprint
page = session.get('https://quotes.toscrape.com/', stealthy_headers=True)
quotes = page.css('.quote .text::text').getall()
# Or use one-off requests
page = Fetcher.get('https://quotes.toscrape.com/')
quotes = page.css('.quote .text::text').getall()
Advanced stealth mode
from scrapling.fetchers import StealthyFetcher, StealthySession
with StealthySession(headless=True, solve_cloudflare=True) as session: # Keep the browser open until you finish
page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False)
data = page.css('#padded_content a').getall()
# Or use one-off request style, it opens the browser for this request, then closes it after finishing
page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare', solve_cloudflare=True)
data = page.css('#padded_content a').getall()
Full browser automation
from scrapling.fetchers import StealthyFetcher, StealthySession
with StealthySession(headless=True, disable_resources=False, network_idle=True) as session: # Keep the browser open until you finish
page = session.fetch('https://quotes.toscrape.com/', load_dom=False)
data = page.xpath('//span[@class="text"]/text()').getall() # XPath selector if you prefer it
# Or use one-off request style, it opens the browser for this request, then closes it after finishing
page = StealthyFetcher.fetch('https://quotes.toscrape.com/')
data = page.css('.quote .text::text').getall()
Build full crawlers with concurrent requests, multiple session types, and pause/resume:
from scrapling.spiders import Spider, Response
class QuotesSpider(Spider):
name = "quotes"
start_urls = ["https://quotes.toscrape.com/"]
concurrent_requests = 10
async def parse(self, response: Response):
for quote in response.css('.quote'):
yield {
"text": quote.css('.text::text').get(),
"author": quote.css('.author::text').get(),
}
next_page = response.css('.next a')
if next_page:
yield response.follow(next_page[0].attrib['href'])
result = QuotesSpider().start()
print(f"Scraped {len(result.items)} quotes")
result.items.to_json("quotes.json")
Use multiple session types in a single spider:
from scrapling.spiders import Spider, Request, Response
from scrapling.fetchers import FetcherSession, AsyncStealthySession
class MultiSessionSpider(Spider):
name = "multi"
start_urls = ["https://example.com/"]
def configure_sessions(self, manager):
manager.add("fast", FetcherSession(impersonate="chrome"))
manager.add("stealth", AsyncStealthySession(headless=True), lazy=True)
async def parse(self, response: Response):
for link in response.css('a::attr(href)').getall():
# Route protected pages through the stealth session
if "protected" in link:
yield Request(link, sid="stealth")
else:
yield Request(link, sid="fast", callback=self.parse) # explicit callback
Pause and resume long crawls with checkpoints by running the spider like this:
QuotesSpider(crawldir="./crawl_data").start()
With crawldir set, press Ctrl+C to save pending requests and seen URLs. Restart with the same crawldir to resume. Save scraped items separately.
Or skip writing the crawling logic altogether with the ready-made templates, like pulling an entire Shopify store's catalog:
from scrapling.spiders import ShopifySpider
class MyStore(ShopifySpider):
target_website = "example.com"
result = MyStore().start() # Every product in the store, one item per variant
The template reads products exposed through public collection endpoints, one item per variant.
from scrapling.fetchers import Fetcher
# Rich element selection and navigation
page = Fetcher.get('https://quotes.toscrape.com/')
# Get quotes with multiple selection methods
quotes = page.css('.quote') # CSS selector
quotes = page.xpath('//div[@class="quote"]') # XPath
quotes = page.find_all('div', {'class': 'quote'}) # BeautifulSoup-style
# Same as
quotes = page.find_all('div', class_='quote')
quotes = page.find_all(['div'], class_='quote')
quotes = page.find_all(class_='quote') # and so on...
# Find element by text content
quotes = page.find_by_text('Albert Einstein', first_match=False)
# Advanced navigation
quote_text = page.css('.quote')[0].css('.text::text').get()
quote_texts = page.css('.quote').css('.text::text').getall() # Chained selectors
first_quote = page.css('.quote')[0]
author = first_quote.css('.author::text').get()
next_quote = first_quote.next
parent_container = first_quote.parent
# Element relationships and similarity
similar_elements = first_quote.find_similar()
below_elements = first_quote.below_elements
You can use the parser right away if you don't want to fetch websites like below:
from scrapling.parser import Selector
page = Selector("<html>...</html>")
And it works precisely the same way!
import asyncio
from scrapling.fetchers import FetcherSession, AsyncStealthySession
async def main():
async with FetcherSession(http3=True) as http_session: # `FetcherSession` is context-aware and can work in both sync/async patterns
page1 = await http_session.get('https://quotes.toscrape.com/')
page2 = await http_session.get('https://quotes.toscrape.com/page/2/', impersonate='chrome')
print(len(page1.css('.quote')), len(page2.css('.quote')))
async with AsyncStealthySession(max_pages=2) as browser_session:
urls = ['https://quotes.toscrape.com/js/', 'https://quotes.toscrape.com/js/page/2/']
pages = await asyncio.gather(*(browser_session.fetch(url, wait_selector='.quote') for url in urls))
print([len(page.css('.quote')) for page in pages])
asyncio.run(main())
Scrapling includes a powerful command-line interface:
Launch the interactive Web Scraping shell
pip install "scrapling[shell]"
scrapling shell
Extract pages to a file directly without programming. Use --css-selector to pick the content, or --ai-targeted to select and sanitize the body content. Use .txt for text, .md for Markdown, or .html for HTML.
scrapling extract get 'https://quotes.toscrape.com/' quotes.md
scrapling extract get 'https://quotes.toscrape.com/' quotes.txt --css-selector '.quote' --impersonate 'chrome'
scrapling extract fetch 'https://quotes.toscrape.com/js/' quotes.md --css-selector '.quote' --wait-selector '.quote' --no-headless
scrapling extract fetch 'https://nopecha.com/demo/cloudflare' captchas.html --css-selector '#padded_content a' --solve-cloudflare
[!NOTE] There are many additional features, but we want to keep this page concise, including the MCP server and the interactive Web Scraping Shell. Check out the full documentation here
Scrapling isn't just powerful-it's also blazing fast. The following benchmarks compare Scrapling's parser with the latest versions of other popular libraries.
| # | Library | Time (ms) | vs Scrapling |
|---|---|---|---|
| 1 | Scrapling | 1.99 | 1.0x |
| 2 | Parsel/Scrapy | 2.06 | 1.035 |
| 3 | Raw Lxml | 2.56 | 1.286 |
| 4 | PyQuery | 23.98 | ~12x |
| 5 | Selectolax | 197.02 | ~99x |
| 6 | MechanicalSoup | 1545.15 | ~776.5x |
| 7 | BS4 with Lxml | 1562.1 | ~785.0x |
| 8 | BS4 with html5lib | 3412.73 | ~1714.9x |
Scrapling's adaptive element finding capabilities significantly outperform alternatives:
| Library | Time (ms) | vs Scrapling |
|---|---|---|
| Scrapling | 2.3 | 1.0x |
| AutoScraper | 12.58 | 5.47x |
All benchmarks represent averages of 100+ runs. See benchmarks.py for methodology.
Scrapling requires Python 3.10 or higher:
pip install scrapling
[!IMPORTANT] This installation only includes the parser engine and its dependencies, without any fetchers or commandline dependencies. So importing anything from
scrapling.fetchersorscrapling.spiders, like in the examples above, will raiseModuleNotFoundErrorwith this installation alone. If you are going to use any of the fetchers or spiders, install the fetchers' dependencies first as shown below.
If you are going to use any of the extra features below, the fetchers, or their classes, you will need to install fetchers' dependencies and their browser dependencies as follows:
pip install "scrapling[fetchers]"
scrapling install # normal install
scrapling install --force # force reinstall
This downloads all browsers, along with their system dependencies and fingerprint manipulation dependencies.
Or you can install them from the code instead of running a command like this:
from scrapling.cli import install
install([], standalone_mode=False) # normal install
install(["--force"], standalone_mode=False) # force reinstall
Extra features:
pip install "scrapling[ai]"
pip install "scrapling[rag]"
extract command):
pip install "scrapling[shell]"
pip install "scrapling[all]"
Run scrapling install when you need browser fetchers. HTTP requests do not need a browser installation.
You can also install a Docker image with all extras and browsers with the following command from DockerHub:
docker pull pyd4vinci/scrapling
Or download it from the GitHub registry:
docker pull ghcr.io/d4vinci/scrapling:latest
This image is automatically built and pushed using GitHub Actions and the repository's main branch.
We welcome contributions! Please read our contributing guidelines before getting started.
[!CAUTION] This library is provided for educational and research purposes only. By using this library, you agree to comply with local and international data scraping and privacy laws. The authors and contributors are not responsible for any misuse of this software. Always respect the terms of service of websites and robots.txt files.
If you have used our library for research purposes please quote us with the following reference:
@misc{scrapling,
author = {Karim Shoair},
title = {Scrapling},
year = {2024},
url = {https://github.com/D4Vinci/Scrapling},
note = {A Python Web Scraping framework for everything from a single request to a full-scale crawl!}
}
This work is licensed under the BSD-3-Clause License.
This project includes code adapted from:
Designed & crafted with ❤️ by Karim Shoair.
内容由编辑整理,部分信息来自 GitHub 与项目官网,版权归原作者所有。发现错误?报告问题