Skip to content

Commit 333fa22

Browse files
authored
v0.4.15 (#423)
2 parents 4ce0fb1 + d04613e commit 333fa22

73 files changed

Lines changed: 4113 additions & 778 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/docker-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
workflow_dispatch:
99
inputs:
1010
version:
11-
description: "Release version to tag the images with, like 'v0.4.14'. Leave it empty to only push 'latest'"
11+
description: "Release version to tag the images with, like 'v0.4.15'. Leave it empty to only push 'latest'"
1212
required: false
1313
default: ''
1414

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373
- name: Install all browsers dependencies
7474
run: |
7575
python3 -m pip install --upgrade pip
76-
python3 -m pip install playwright==1.61.0 patchright==1.61.2
76+
python3 -m pip install playwright==1.62.0 patchright==1.62.1
7777
7878
- name: Get Playwright version
7979
id: playwright-version

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ local_tests/*
66
# AI related files
77
.claude/*
88
CLAUDE.md
9+
tasks/*
910

1011
# cached files
1112
__pycache__/

CHANGELOG.md

Lines changed: 1229 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
<a href="https://hub.docker.com/r/pyd4vinci/scrapling" target="_blank">
2424
<img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/pyd4vinci/scrapling?labelColor=%20%23FDB062&logo=Docker&labelColor=%20%23528bff"></a>
2525
<a href="https://clickpy.clickhouse.com/dashboard/scrapling" rel="nofollow"><img src="https://img.shields.io/pypi/dm/scrapling" alt="PyPI package downloads"></a>
26-
<a href="https://github.com/D4Vinci/Scrapling/tree/main/agent-skill" alt="AI Agent Skill directory">
27-
<img alt="Static Badge" src="https://img.shields.io/badge/Skill-black?style=flat&label=Agent&link=https%3A%2F%2Fgithub.qkg1.top%2FD4Vinci%2FScrapling%2Ftree%2Fmain%2Fagent-skill"></a>
26+
<a href="https://scrapling.readthedocs.io/en/latest/ai/agent-skill.html" alt="AI Agent Skill">
27+
<img alt="Static Badge" src="https://img.shields.io/badge/Skill-black?style=flat&label=Agent&link=https%3A%2F%2Fscrapling.readthedocs.io%2Fen%2Flatest%2Fai%2Fagent-skill.html"></a>
2828
<a href="https://clawhub.ai/D4Vinci/scrapling-official" alt="OpenClaw Skill">
2929
<img alt="OpenClaw Skill" src="https://img.shields.io/badge/Clawhub-darkred?style=flat&label=OpenClaw&link=https%3A%2F%2Fclawhub.ai%2FD4Vinci%2Fscrapling-official"></a>
3030
<br/>
@@ -55,7 +55,7 @@
5555

5656
Scrapling is an adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl.
5757

58-
Its parser learns from website changes and automatically relocates your elements when pages update. Its fetchers bypass anti-bot systems like Cloudflare Turnstile out of the box. And its spider framework lets you scale up to concurrent, multi-session crawls with pause/resume and automatic proxy rotation - all in a few lines of Python. One library, zero compromises.
58+
Its parser learns from website changes and automatically relocates your elements when pages update. Its fetchers bypass anti-bot systems like Cloudflare Turnstile out of the box. And its spider framework lets you scale up to concurrent, multi-session crawls with pause/resume, automatic proxy rotation, and a crawl speed that adapts to how fast each website responds and backs off when it starts blocking you - all in a few lines of Python. One library, zero compromises.
5959

6060
Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers for Web Scrapers and regular users, there's something for everyone.
6161

@@ -266,12 +266,15 @@ MySpider().start()
266266
- **Background API Capture**: Pass a URL pattern to `capture_xhr`, and all matching XHR/fetch responses the page makes while loading are collected for you as `Response` objects in `response.captured_xhr` - grab a site's API data without reverse-engineering the requests yourself.
267267
- **Async Support**: Complete async support across all fetchers and dedicated async session classes.
268268

269-
### Adaptive Scraping & AI Integration
269+
### Adaptive Scraping
270270
- 🔄 **Smart Element Tracking**: Relocate elements after website changes using intelligent similarity algorithms.
271271
- 🎯 **Smart Flexible Selection**: CSS selectors, XPath selectors, filter-based search, text search, regex search, and more.
272272
- 🔍 **Find Similar Elements**: Automatically locate elements similar to found elements.
273-
- 🤖 **MCP Server to be used with AI**: Built-in MCP server for AI-assisted Web Scraping and data extraction. The MCP server features powerful, custom capabilities that leverage Scrapling to extract targeted content before passing it to the AI (Claude/Cursor/etc), thereby speeding up operations and reducing costs by minimizing token usage. ([demo video](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) It can also keep browser sessions open across calls, take page screenshots, and drive remote browsers over CDP.
274-
- 🧠 **Agent Skill**: A ready-to-install [Agent Skill](https://github.com/D4Vinci/Scrapling/tree/main/agent-skill) that teaches coding agents the whole library, so the code they write with Scrapling matches the current API instead of guessing.
273+
274+
### AI Features
275+
- 🤖 **MCP Server**: Let AI chatbots and agents (Claude/Cursor/etc) scrape through Scrapling with one-shot or session-based tools covering plain HTTP requests (any method), browser fetches, and stealth fetches that bypass Cloudflare. Pages are narrowed with CSS selectors and stripped of prompt-injection content before the AI sees them, so the agent reads less, costs less, and can't be hijacked by hidden text. Screenshots, remote browsers over CDP, and a secure-by-default HTTP transport are included. ([demo video](https://www.youtube.com/watch?v=qyFk3ZNwOxE))
276+
- 🧠 **Agent Skill**: A ready-to-install [Agent Skill](https://scrapling.readthedocs.io/en/latest/ai/agent-skill.html) that teaches coding agents the whole library, so the code they write with Scrapling matches the current API instead of guessing.
277+
- 📚 **RAG-ready Markdown**: Turn any page into clean, sanitized, LLM-ready Markdown with one line (`page.markdown()`), or crawl a whole website into a Markdown corpus with the `SiteToMarkdownSpider` template, all without an LLM in the loop. ([docs](https://scrapling.readthedocs.io/en/latest/ai/building-rag-systems.html))
275278

276279
### High-Performance & battle-tested Architecture
277280
- 🚀 **Lightning Fast**: Optimized performance outperforming most Python scraping libraries.
@@ -541,6 +544,10 @@ pip install scrapling
541544
```bash
542545
pip install "scrapling[ai]"
543546
```
547+
- Install dependencies for ([building RAG systems](https://scrapling.readthedocs.io/en/latest/ai/building-rag-systems.html)):
548+
```bash
549+
pip install "scrapling[rag]"
550+
```
544551
- Install shell features (Web Scraping shell and the `extract` command):
545552
```bash
546553
pip install "scrapling[shell]"

agent-skill/Scrapling-Skill.zip

4.3 KB
Binary file not shown.

agent-skill/Scrapling-Skill/SKILL.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: scrapling-official
33
description: Scrape web pages using Scrapling with anti-bot bypass (like Cloudflare Turnstile), stealth headless browsing, spiders framework, adaptive scraping, and JavaScript rendering. Use when asked to scrape, crawl, or extract data from websites; web_fetch fails; the site has anti-bot protections; write Python code to scrape/crawl; or write spiders.
4-
version: "0.4.14"
4+
version: "0.4.15"
55
license: Complete terms in LICENSE.txt
66
metadata:
77
homepage: "https://scrapling.readthedocs.io/en/latest/index.html"
@@ -40,7 +40,7 @@ Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers fo
4040

4141
Create a virtual Python environment through any way available, like `venv`, then inside the environment do:
4242

43-
`pip install "scrapling[all]>=0.4.14"`
43+
`pip install "scrapling[all]>=0.4.15"`
4444

4545
Then do this to download all the browsers' dependencies:
4646

@@ -398,6 +398,7 @@ async with AsyncDynamicSession(capture_xhr=r"https://api\.example\.com/.*") as s
398398
## References
399399
You already had a good glimpse of what the library can do. Use the references below to dig deeper when needed
400400
- `references/mcp-server.md` - MCP server tools, persistent session management, remote browsers over CDP, authentication, and capabilities
401+
- `references/building-rag-systems.md` - Converting pages/websites to LLM-ready Markdown with `Response.markdown()` and `SiteToMarkdownSpider` for RAG pipelines
401402
- `references/parsing` - Everything you need for parsing HTML
402403
- `references/fetching` - Everything you need to fetch websites and session persistence
403404
- `references/spiders` - Everything you need to write spiders, proxy rotation, and advanced features. It follows a Scrapy-like format

agent-skill/Scrapling-Skill/examples/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ All examples collect **all 100 quotes across 10 pages**.
99
Make sure Scrapling is installed:
1010

1111
```bash
12-
pip install "scrapling[all]>=0.4.14"
12+
pip install "scrapling[all]>=0.4.15"
1313
scrapling install --force
1414
```
1515

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Building RAG Systems
2+
3+
RAG pipelines are only as good as the text you feed them. Raw HTML wastes tokens on markup, navigation, scripts, and tracking noise, and it can even carry hidden prompt-injection content straight into your LLM. Scrapling turns pages and whole websites into clean, sanitized Markdown with no LLM in the loop, so your ingestion runs fast and costs nothing per page.
4+
5+
## Installation
6+
7+
```bash
8+
pip install "scrapling[rag]"
9+
10+
scrapling install
11+
```
12+
13+
The `rag` extra installs the fetchers with Markdown conversion support (the `ai`, `shell`, and `all` extras include it too). The `scrapling install` command downloads the browser dependencies, which you only need for the browser-based fetchers.
14+
15+
## One page to Markdown
16+
17+
Every [Response](fetching/choosing.md) has a `markdown()` method:
18+
19+
```python
20+
from scrapling.fetchers import Fetcher
21+
22+
markdown = Fetcher.get("https://example.com").markdown(main_content_only=True)
23+
```
24+
25+
It works with all fetchers, so pages behind Cloudflare are one line away too:
26+
27+
```python
28+
from scrapling.fetchers import StealthyFetcher
29+
30+
markdown = StealthyFetcher.fetch("https://protected.example.com", solve_cloudflare=True).markdown(main_content_only=True)
31+
```
32+
33+
Two arguments control the output:
34+
35+
- `main_content_only`: Convert only the content inside the page's `<body>` tag.
36+
- `css_selector`: Convert only the elements matching a CSS selector (all matches are concatenated). Use it to extract exactly the part your pipeline needs and save tokens:
37+
38+
```python
39+
markdown = Fetcher.get("https://example.com/docs/page").markdown(css_selector="article")
40+
```
41+
42+
Whatever you pass, scripts, styles, and hidden content are always removed before conversion. This is the same cleaning the [MCP server](mcp-server.md) uses to protect AI agents from prompt injection: CSS-hidden elements, `aria-hidden` elements, `<template>` tags, HTML comments, and zero-width characters never reach your model.
43+
44+
## A whole website to a Markdown corpus
45+
46+
The `SiteToMarkdownSpider` template crawls a website and converts every page, powered by the [spiders framework](spiders/architecture.md), so you get concurrency, autothrottle, robots.txt compliance, and pause/resume for free:
47+
48+
```python
49+
from scrapling.spiders import SiteToMarkdownSpider
50+
51+
class DocsSpider(SiteToMarkdownSpider):
52+
name = "docs"
53+
start_urls = ["https://example.com/docs/"]
54+
allowed_domains = {"example.com"}
55+
output_dir = "docs_markdown"
56+
max_pages = 200
57+
58+
result = DocsSpider().start()
59+
result.items.to_jsonl("docs.jsonl")
60+
```
61+
62+
Each crawled page becomes one item with `url`, `title`, and `markdown` keys. With `output_dir` set, each page is also written to a Markdown file named after its URL, so the run above gives you both a folder of `.md` files and a `docs.jsonl` ready for ingestion.
63+
64+
The template requires `allowed_domains` so the crawl stays bound to the target website. The options:
65+
66+
- `css_selector` / `main_content_only`: Passed to `markdown()` for every page, with `main_content_only` enabled by default.
67+
- `output_dir`: When set, writes one Markdown file per page.
68+
- `max_pages`: Maximum number of pages to convert. Requests already queued when the cap hits may still be fetched, but they aren't converted. `0` (the default) disables it.
69+
70+
Every page link inside `allowed_domains` is followed by default. Since the template builds on [CrawlSpider](spiders/generic-templates.md), override `rules()` with your own [LinkExtractor](spiders/generic-templates.md) to control the crawl: `allow` narrows it to the URL patterns you want, and `deny` drops the patterns you don't (login pages, tag listings, print views, etc.):
71+
72+
```python
73+
from scrapling.spiders import CrawlRule, LinkExtractor, SiteToMarkdownSpider
74+
75+
class DocsSpider(SiteToMarkdownSpider):
76+
name = "docs"
77+
start_urls = ["https://example.com/"]
78+
allowed_domains = {"example.com"}
79+
80+
def rules(self):
81+
return [CrawlRule(LinkExtractor(allow=r"/docs/", deny=[r"/docs/changelog/", r"\?print="]))]
82+
```
83+
84+
`deny` wins over `allow`, and a rule can carry a `priority` or a `process_request` hook as with any **CrawlSpider**.
85+
86+
## Feeding a vector store
87+
88+
The JSONL output plugs into any embedding pipeline. A minimal example:
89+
90+
```python
91+
import json
92+
93+
with open("docs.jsonl") as f:
94+
for line in f:
95+
page = json.loads(line)
96+
for chunk in split_into_chunks(page["markdown"]):
97+
vector_store.add(text=chunk, metadata={"url": page["url"], "title": page["title"]})
98+
```
99+
100+
Use `css_selector` on the spider to cut boilerplate before chunking instead of cleaning it downstream. The less noise you embed, the better your retrieval.
101+
102+
## Interactive alternatives
103+
104+
For conversational scraping instead of pipelines, the [MCP server](mcp-server.md) gives your AI chatbot the same Markdown extraction as tools, and this agent skill teaches coding agents to write this code themselves.

agent-skill/Scrapling-Skill/references/fetching/choosing.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,10 @@ page.captured_xhr # List of captured XHR/fetch responses (when capture_xhr is
7575
```
7676
All fetchers return the `Response` object.
7777

78+
The `Response` object can also convert the page to clean, LLM-ready Markdown in one line:
79+
```python
80+
markdown = Fetcher.get('https://example.com').markdown(main_content_only=True)
81+
```
82+
Scripts, styles, and hidden/prompt-injection content are always removed before conversion, and you can pass `css_selector` to convert specific elements only. It requires the `rag` extra (included in `ai`/`shell`/`all` too). See `../building-rag-systems.md` for the full guide.
83+
7884
**Note:** Unlike the [Selector](parsing/main_classes.md#selector) class, the `Response` class's body is always bytes since v0.4.

0 commit comments

Comments
 (0)