scrapling
Write scrapers with the official Scrapling 0.4.14 API (Fetcher, StealthyFetcher, DynamicFetcher, sessions, Spider templates, adaptive CSS). Default framework in the Scraping module. Fall back to the scrape tool or browser only when Scrapling is the wrong tool.
Install
npx skills add https://github.com/Navinspire-ia/navin/tree/main/navin/skills/scrapling
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install navinspire-ia-navin@llmmart
git clone https://github.com/Navinspire-ia/navin.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole navinspire-ia/navin collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Scrapling 0.4.14
Official adaptive scraping framework (D4Vinci). Pin scrapling==0.4.14. Use only this API. Do not invent methods or mix BeautifulSoup / raw Playwright unless the user named that stack.
Docs: https://scrapling.readthedocs.io/en/latest/
In the Scraping module this is the default, the same way Code uses the Dev stack and Leads uses prospecting scripts.
Choose a layer
| Need | Use |
|---|---|
| Static HTML, TLS impersonation | Fetcher / FetcherSession |
| Cloudflare Turnstile / stealth | StealthyFetcher / StealthySession (solve_cloudflare=True) |
| Full JS browser (Playwright Chromium / Chrome) | DynamicFetcher / DynamicSession |
| Multi-page crawl, pause/resume, export | Spider (or a template below) |
| Parse HTML you already have | Selector from scrapling.parser |
| One-shot corpus, no new Python | Navin scrape tool (Rust / httpx) |
| Forms, multi-tab, upload, human walls in Navin UI | Navin browser tool |
Read references/api.md for sessions, spiders, templates, CLI, and MCP.
Install (required before fetchers/spiders)
pip install scrapling is parser only. from scrapling.fetchers or from scrapling.spiders fails without extras.
pip install "scrapling[fetchers]==0.4.14"
scrapling install
Repo extra: pip install -e ".[scraping]" then scrapling install.
- MCP:
pip install "scrapling[ai]==0.4.14" - Shell /
scrapling extract:pip install "scrapling[shell]==0.4.14" - Everything:
pip install "scrapling[all]==0.4.14"thenscrapling install
If import fails, install via exec, then retry. Do not silently switch stack.
Canonical fetch + adaptive select
from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher
StealthyFetcher.adaptive = True
page = StealthyFetcher.fetch(
"https://example.com",
headless=True,
network_idle=True,
)
products = page.css(".product", auto_save=True)
# After a redesign:
products = page.css(".product", adaptive=True)
HTTP with session + Chrome TLS:
from scrapling.fetchers import Fetcher, FetcherSession
with FetcherSession(impersonate="chrome") as session:
page = session.get("https://quotes.toscrape.com/", stealthy_headers=True)
quotes = page.css(".quote .text::text").getall()
page = Fetcher.get("https://quotes.toscrape.com/")
Stealth / Cloudflare:
from scrapling.fetchers import StealthyFetcher, StealthySession
with StealthySession(headless=True, solve_cloudflare=True) as session:
page = session.fetch("https://nopecha.com/demo/cloudflare", google_search=False)
data = page.css("#padded_content a").getall()
page = StealthyFetcher.fetch("https://nopecha.com/demo/cloudflare")
Full browser:
from scrapling.fetchers import DynamicFetcher, DynamicSession
with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session:
page = session.fetch("https://quotes.toscrape.com/", load_dom=False)
data = page.xpath('//span[@class="text"]/text()').getall()
page = DynamicFetcher.fetch("https://quotes.toscrape.com/")
Canonical spider
from scrapling.spiders import Spider, Request, 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(),
"url": response.url,
}
next_page = response.css(".next a")
if next_page:
yield response.follow(next_page[0].attrib["href"])
result = QuotesSpider().start()
result.items.to_json("scrape/quotes.json")
Pause / resume: QuotesSpider(crawldir="./scrape/crawl_data").start(). Ctrl+C saves; same crawldir resumes.
Ready-made templates (prefer these over a blank spider when they fit): CrawlSpider, SitemapSpider, XMLFeedSpider, CSVFeedSpider, ShopifySpider.
from scrapling.spiders import ShopifySpider
class MyStore(ShopifySpider):
target_website = "example.com"
result = MyStore().start()
Parse without fetching
from scrapling.parser import Selector
page = Selector("<html>...</html>")
quotes = page.css(".quote")
quotes = page.xpath('//div[@class="quote"]')
quotes = page.find_all("div", class_="quote")
quotes = page.find_by_text("quote", tag="div")
Selection: CSS, XPath, find_all, find_by_text, chained .css(), ::text / ::attr(href) like Scrapy/Parsel. Navigation: .parent, .next_sibling, .find_similar(), .below_elements(). Adaptive: auto_save=True then later adaptive=True.
Delivery in Navin
- Write scripts under
scrape/build/. Pinscrapling==0.4.14in any requirements file. - Deliver the exported dataset and the report, not the spider. Hand over scraper code only when the user asked for it.
- Export with
result.items.to_json()/to_jsonl()/to_csv()/to_xml(), or Navinscrapeexport. - Keep a source URL on every row. Never dump corpora into chat.
robots_txt_obeyon spiders when the user cares about compliance.- Captcha / paywall / login that still blocks after StealthyFetcher: pause and use the Navin
browsertool with the user. Do not sell bypass as a guarantee.
Fallback (do not skip)
- Scrapling 0.4.14 for code the agent writes or runs.
- Navin
scrapetool for a ready-made fetch/crawl/export (Rust, else httpx). - Navin
browserfor interactive UI, empty JS shells after Scrapling, or assisted walls.
Files (navin)
-
references
-
api.md 4.8 KB
# Scrapling 0.4.14 API notes Load this when writing sessions, multi-session spiders, CLI, or MCP. Keep `scrapling==0.4.14`. ## Fetchers | Class | Role | |---|---| | `Fetcher` / `AsyncFetcher` | Fast HTTP. TLS impersonation, headers, HTTP/3. | | `StealthyFetcher` | Stealth + fingerprint. Cloudflare Turnstile / interstitial. | | `DynamicFetcher` | Full browser (Playwright Chromium or Chrome). | | `FetcherSession` | Persistent HTTP cookies/state. Sync and async context. | | `StealthySession` / `AsyncStealthySession` | Persistent stealth browser. | | `DynamicSession` / `AsyncDynamicSession` | Persistent full browser. | Useful kwargs (official examples): `impersonate='chrome'`, `stealthy_headers=True`, `http3=True`, `headless=True`, `network_idle=True`, `solve_cloudflare=True`, `google_search=False`, `disable_resources=False`, `load_dom=False`, `max_pages=2`, `cdp_url` (remote browser), `executable_path` (own Chromium), `capture_xhr` (collect matching XHR as `response.captured_xhr`). Proxy: built-in `ProxyRotator` on sessions; per-request proxy override. Optional DoH via Cloudflare to avoid DNS leaks. Browser fetchers can block domains or ~3500 ad/tracker hosts. ### Async sessions ```python import asyncio from scrapling.fetchers import FetcherSession, AsyncStealthySession async with FetcherSession(http3=True) as session: page1 = session.get("https://quotes.toscrape.com/") page2 = session.get("https://quotes.toscrape.com/", impersonate="firefox135") async with AsyncStealthySession(max_pages=2) as session: urls = ["https://example.com/page1", "https://example.com/page2"] results = await asyncio.gather(*(session.fetch(url) for url in urls)) print(session.get_pool_stats()) ``` ## Spiders `Spider` is Scrapy-like: `name`, `start_urls`, async `parse`, `Request` / `Response`, `response.follow`. - Concurrency: `concurrent_requests`, per-domain throttle, download delay, AutoThrottle. - Multi-session: `configure_sessions(manager)` then `yield Request(url, sid="stealth")`. - Pause/resume: `crawldir=...`; Ctrl+C graceful; restart with the same dir. - Streaming: `async for item in spider.stream()`. - Blocked-request detect + retry. Optional `robots_txt_obey`. - Dev mode: cache responses to disk and replay `parse()` without re-hitting the site. - Export: `result.items.to_json()` / `to_jsonl()` / `to_csv()` / `to_xml()`. - `LinkExtractor`: allow/deny, domains, CSS/XPath scope, extensions, canonicalization. ```python 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(): if "protected" in link: yield Request(link, sid="stealth") else: yield Request(link, sid="fast", callback=self.parse) ``` ### Templates | Template | Use | |---|---| | `CrawlSpider` | Rule-based link following | | `SitemapSpider` | sitemap / robots.txt seeds | | `XMLFeedSpider` / `CSVFeedSpider` | XML/RSS or CSV feeds | | `ShopifySpider` | Every product via Shopify JSON API, one item per variant (`target_website`) | ## CLI Needs `scrapling[shell]` (or `[all]`) plus `scrapling install` if browsers are used. ```bash scrapling shell scrapling extract get 'https://example.com' scrape/content.md scrapling extract get 'https://example.com' scrape/content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome' scrapling extract fetch 'https://example.com' scrape/content.md --css-selector '#fromSkipToProducts' --no-headless scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' scrape/captchas.html --css-selector '#padded_content a' --solve-cloudflare ``` `.txt` = text, `.md` = markdown of HTML, `.html` = raw HTML. Default extract is the `body` content. Reinstall browsers from code if the CLI is unavailable: ```python from scrapling.cli import install install([], standalone_mode=False) install(["--force"], standalone_mode=False) ``` ## MCP / AI extra `pip install "scrapling[ai]==0.4.14"`. Official MCP keeps browser sessions, can screenshot, and can drive remote browsers over CDP. Prefer Navin tools for delivery in this product; use Scrapling MCP only if the user asked for it. ## Scrapy interop If the project already uses Scrapy, decorate a callback with `scrapling_response` and parse with Scrapling. Do not rewrite a working Scrapy spider unless asked. ## Navin fallbacks Still apply after this API: `scrape` tool for no-code corpora; `browser` for assisted walls and Navin-driven UI. Do not copy sponsor proxy ads into generated code.
-
-
SKILL.md 5.9 KB
--- name: scrapling description: Write scrapers with the official Scrapling 0.4.14 API (Fetcher, StealthyFetcher, DynamicFetcher, sessions, Spider templates, adaptive CSS). Default framework in the Scraping module. Fall back to the scrape tool or browser only when Scrapling is the wrong tool. metadata: {"navin":{"emoji":"🕷️","category":"navigation"}} --- # Scrapling 0.4.14 Official adaptive scraping framework (D4Vinci). Pin **`scrapling==0.4.14`**. Use only this API. Do not invent methods or mix BeautifulSoup / raw Playwright unless the user named that stack. Docs: https://scrapling.readthedocs.io/en/latest/ In the **Scraping** module this is the default, the same way Code uses the Dev stack and Leads uses prospecting scripts. ## Choose a layer | Need | Use | |---|---| | Static HTML, TLS impersonation | `Fetcher` / `FetcherSession` | | Cloudflare Turnstile / stealth | `StealthyFetcher` / `StealthySession` (`solve_cloudflare=True`) | | Full JS browser (Playwright Chromium / Chrome) | `DynamicFetcher` / `DynamicSession` | | Multi-page crawl, pause/resume, export | `Spider` (or a template below) | | Parse HTML you already have | `Selector` from `scrapling.parser` | | One-shot corpus, no new Python | Navin `scrape` tool (Rust / httpx) | | Forms, multi-tab, upload, human walls in Navin UI | Navin `browser` tool | Read [references/api.md](references/api.md) for sessions, spiders, templates, CLI, and MCP. ## Install (required before fetchers/spiders) `pip install scrapling` is **parser only**. `from scrapling.fetchers` or `from scrapling.spiders` fails without extras. ```bash pip install "scrapling[fetchers]==0.4.14" scrapling install ``` Repo extra: `pip install -e ".[scraping]"` then `scrapling install`. - MCP: `pip install "scrapling[ai]==0.4.14"` - Shell / `scrapling extract`: `pip install "scrapling[shell]==0.4.14"` - Everything: `pip install "scrapling[all]==0.4.14"` then `scrapling install` If import fails, install via `exec`, then retry. Do not silently switch stack. ## Canonical fetch + adaptive select ```python from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher StealthyFetcher.adaptive = True page = StealthyFetcher.fetch( "https://example.com", headless=True, network_idle=True, ) products = page.css(".product", auto_save=True) # After a redesign: products = page.css(".product", adaptive=True) ``` HTTP with session + Chrome TLS: ```python from scrapling.fetchers import Fetcher, FetcherSession with FetcherSession(impersonate="chrome") as session: page = session.get("https://quotes.toscrape.com/", stealthy_headers=True) quotes = page.css(".quote .text::text").getall() page = Fetcher.get("https://quotes.toscrape.com/") ``` Stealth / Cloudflare: ```python from scrapling.fetchers import StealthyFetcher, StealthySession with StealthySession(headless=True, solve_cloudflare=True) as session: page = session.fetch("https://nopecha.com/demo/cloudflare", google_search=False) data = page.css("#padded_content a").getall() page = StealthyFetcher.fetch("https://nopecha.com/demo/cloudflare") ``` Full browser: ```python from scrapling.fetchers import DynamicFetcher, DynamicSession with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: page = session.fetch("https://quotes.toscrape.com/", load_dom=False) data = page.xpath('//span[@class="text"]/text()').getall() page = DynamicFetcher.fetch("https://quotes.toscrape.com/") ``` ## Canonical spider ```python from scrapling.spiders import Spider, Request, 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(), "url": response.url, } next_page = response.css(".next a") if next_page: yield response.follow(next_page[0].attrib["href"]) result = QuotesSpider().start() result.items.to_json("scrape/quotes.json") ``` Pause / resume: `QuotesSpider(crawldir="./scrape/crawl_data").start()`. Ctrl+C saves; same `crawldir` resumes. Ready-made templates (prefer these over a blank spider when they fit): `CrawlSpider`, `SitemapSpider`, `XMLFeedSpider`, `CSVFeedSpider`, `ShopifySpider`. ```python from scrapling.spiders import ShopifySpider class MyStore(ShopifySpider): target_website = "example.com" result = MyStore().start() ``` ## Parse without fetching ```python from scrapling.parser import Selector page = Selector("<html>...</html>") quotes = page.css(".quote") quotes = page.xpath('//div[@class="quote"]') quotes = page.find_all("div", class_="quote") quotes = page.find_by_text("quote", tag="div") ``` Selection: CSS, XPath, `find_all`, `find_by_text`, chained `.css()`, `::text` / `::attr(href)` like Scrapy/Parsel. Navigation: `.parent`, `.next_sibling`, `.find_similar()`, `.below_elements()`. Adaptive: `auto_save=True` then later `adaptive=True`. ## Delivery in Navin - Write scripts under `scrape/build/`. Pin `scrapling==0.4.14` in any requirements file. - Deliver the exported dataset and the report, not the spider. Hand over scraper code only when the user asked for it. - Export with `result.items.to_json()` / `to_jsonl()` / `to_csv()` / `to_xml()`, or Navin `scrape` `export`. - Keep a source URL on every row. Never dump corpora into chat. - `robots_txt_obey` on spiders when the user cares about compliance. - Captcha / paywall / login that still blocks after StealthyFetcher: pause and use the Navin `browser` tool with the user. Do not sell bypass as a guarantee. ## Fallback (do not skip) 1. Scrapling 0.4.14 for code the agent writes or runs. 2. Navin `scrape` tool for a ready-made fetch/crawl/export (Rust, else httpx). 3. Navin `browser` for interactive UI, empty JS shells after Scrapling, or assisted walls.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.