fromscrapling.fetchersimportFetcher,AsyncFetcher,StealthyFetcher,DynamicFetcherStealthyFetcher.adaptive=Truep=StealthyFetcher.fetch('https://example.com',headless=True,network_idle=True)# Fetch website under the radar!products=p.css('.product',auto_save=True)# Scrape data that survives website design changes!products=p.css('.product',adaptive=True)# Later, if the website structure changes, pass `adaptive=True` to find them!
📘完整的类型覆盖:全面的类型提示,提供出色的 IDE 支持和代码补全。每次变更都会通过 PyRight 和 MyPy 自动扫描整个代码库。
🔋即用型 Docker 镜像:每次发布都会自动构建并推送包含所有浏览器的 Docker 镜像。
快速入门
让我们快速了解一下 Scrapling 的功能,无需深入细节。
基础用法
带会话支持的 HTTP 请求
fromscrapling.fetchersimportFetcher,FetcherSessionwithFetcherSession(impersonate='chrome')assession:# Use latest version of Chrome's TLS fingerprintpage=session.get('https://quotes.toscrape.com/',stealthy_headers=True)quotes=page.css('.quote .text::text').getall()# Or use one-off requestspage=Fetcher.get('https://quotes.toscrape.com/')quotes=page.css('.quote .text::text').getall()
高级隐身模式
fromscrapling.fetchersimportStealthyFetcher,StealthySessionwithStealthySession(headless=True,solve_cloudflare=True)assession:# Keep the browser open until you finishpage=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 finishingpage=StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare')data=page.css('#padded_content a').getall()
完整浏览器自动化
fromscrapling.fetchersimportDynamicFetcher,DynamicSessionwithDynamicSession(headless=True,disable_resources=False,network_idle=True)assession:# Keep the browser open until you finishpage=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 finishingpage=DynamicFetcher.fetch('https://quotes.toscrape.com/')data=page.css('.quote .text::text').getall()
fromscrapling.spidersimportSpider,Request,Responsefromscrapling.fetchersimportFetcherSession,AsyncStealthySessionclassMultiSessionSpider(Spider):name="multi"start_urls=["https://example.com/"]defconfigure_sessions(self,manager):manager.add("fast",FetcherSession(impersonate="chrome"))manager.add("stealth",AsyncStealthySession(headless=True),lazy=True)asyncdefparse(self,response:Response):forlinkinresponse.css('a::attr(href)').getall():# Route protected pages through the stealth sessionif"protected"inlink:yieldRequest(link,sid="stealth")else:yieldRequest(link,sid="fast",callback=self.parse)# explicit callback
fromscrapling.fetchersimportFetcher# Rich element selection and navigationpage=Fetcher.get('https://quotes.toscrape.com/')# Get quotes with multiple selection methodsquotes=page.css('.quote')# CSS selectorquotes=page.xpath('//div[@class="quote"]')# XPathquotes=page.find_all('div',{'class':'quote'})# BeautifulSoup-style# Same asquotes=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 contentquotes=page.find_by_text('quote',tag='div')# Advanced navigationquote_text=page.css('.quote')[0].css('.text::text').get()quote_text=page.css('.quote').css('.text::text').getall()# Chained selectorsfirst_quote=page.css('.quote')[0]author=first_quote.next_sibling.css('.author::text')parent_container=first_quote.parent# Element relationships and similaritysimilar_elements=first_quote.find_similar()below_elements=first_quote.below_elements()
importasynciofromscrapling.fetchersimportFetcherSession,AsyncStealthySession,AsyncDynamicSessionasyncwithFetcherSession(http3=True)assession:# `FetcherSession` is context-aware and can work in both sync/async patternspage1=session.get('https://quotes.toscrape.com/')page2=session.get('https://quotes.toscrape.com/',impersonate='firefox135')# Async session usageasyncwithAsyncStealthySession(max_pages=2)assession:tasks=[]urls=['https://example.com/page1','https://example.com/page2']forurlinurls:task=session.fetch(url)tasks.append(task)print(session.get_pool_stats())# Optional - The status of the browser tabs pool (busy/free/error)results=awaitasyncio.gather(*tasks)print(session.get_pool_stats())
CLI 与交互式 Shell
Scrapling 包含一个强大的命令行界面:
启动交互式 Web 抓取 Shell
scrapling shell
无需编程即可直接将页面提取到文件(默认提取 body 标签内的内容)。如果输出文件以 .txt 结尾,则提取目标的文本内容;如果以 .md 结尾,则输出 HTML 内容的 Markdown 表示形式;如果以 .html 结尾,则直接输出 HTML 内容本身。
scrapling extract get 'https://example.com' content.md
scrapling extract get 'https://example.com' content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome'# All elements matching the CSS selector '#fromSkipToProducts'
scrapling extract fetch 'https://example.com' content.md --css-selector '#fromSkipToProducts' --no-headless
scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas.html --css-selector '#padded_content a' --solve-cloudflare
Note
还有很多其他功能,但我们希望此页面保持简洁,包括 MCP 服务器和交互式 Web 抓取 Shell。请在此处查看完整文档:here
@misc{scrapling,
author = {Karim Shoair},
title = {Scrapling},
year = {2024},
url = {https://github.com/D4Vinci/Scrapling},
note = {An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!}
}