Product 1
+Description 1
+diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 320bc88..b798500 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -11,6 +11,7 @@ on: - 'docs/**' - 'images/**' - '.github/**' + - 'agent-skill/**' - '!.github/workflows/code-quality.yml' # Always run when this workflow changes pull_request: branches: @@ -22,6 +23,7 @@ on: - 'docs/**' - 'images/**' - '.github/**' + - 'agent-skill/**' - '*.yml' - '*.yaml' - 'ruff.toml' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d18c2d3..1cf6139 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,6 +10,7 @@ on: - 'docs/**' - 'images/**' - '.github/**' + - 'agent-skill/**' - '*.yml' - '*.yaml' - 'ruff.toml' @@ -23,6 +24,7 @@ on: - 'docs/**' - 'images/**' - '.github/**' + - 'agent-skill/**' - '*.yml' - '*.yaml' - 'ruff.toml' @@ -71,7 +73,7 @@ jobs: - name: Install all browsers dependencies run: | python3 -m pip install --upgrade pip - python3 -m pip install playwright==1.56.0 patchright==1.56.0 + python3 -m pip install playwright==1.58.0 patchright==1.58.2 - name: Get Playwright version id: playwright-version diff --git a/README.md b/README.md index dfae945..b862899 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,17 @@
- العربيه | Español | Français | Deutsch | 简体中文 | 日本語 | Русский
+ العربيه | Español | Français | Deutsch | 简体中文 | 日本語 | Русский | 한국어
-
-
+
+
+
+
+
@@ -88,46 +91,67 @@ MySpider().start()
-
-
-
+
+
+
+
+
-
-
-
-
-
+
diff --git a/agent-skill/README.md b/agent-skill/README.md
new file mode 100644
index 0000000..2719089
--- /dev/null
+++ b/agent-skill/README.md
@@ -0,0 +1,17 @@
+# Scrapling Agent Skill
+
+The skill aligns with the [AgentSkill](https://agentskills.io/specification) specification, so it will be readable by [OpenClaw](https://github.com/openclaw/openclaw), [Claude Code](https://claude.com/product/claude-code), and other agentic tools. It encapsulates almost all of the documentation website's content in Markdown, so the agent doesn't have to guess anything.
+
+It can be used to answer almost 90% of any questions you would have about scrapling. We tested it on [OpenClaw](https://github.com/openclaw/openclaw) and [Claude Code](https://claude.com/product/claude-code), but please open a [ticket](https://github.com/D4Vinci/Scrapling/issues/new/choose) if you faced any issues or use our [Discord server](https://discord.gg/EMgGbDceNQ).
+
+## Installation
+
+You can use this [direct URL](https://github.com/D4Vinci/Scrapling/raw/refs/heads/main/agent-skill/Scrapling-Skill.zip) to download the ZIP file of the skill directly. We will try to update this page with all available methods.
+
+### Clawhub
+If you are an [OpenClaw](https://github.com/openclaw/openclaw) and [Claude Code](https://claude.com/product/claude-code), you can install the skill using [Clawhub](https://docs.openclaw.ai/tools/clawhub) directly:
+```bash
+clawhub install scrapling-official
+```
+
+Or go to the [Clawhub](https://docs.openclaw.ai/tools/clawhub) page from [here](https://clawhub.ai/D4Vinci/scrapling-official).
\ No newline at end of file
diff --git a/agent-skill/Scrapling-Skill.zip b/agent-skill/Scrapling-Skill.zip
new file mode 100644
index 0000000..0bbd64c
Binary files /dev/null and b/agent-skill/Scrapling-Skill.zip differ
diff --git a/agent-skill/Scrapling-Skill/LICENSE.txt b/agent-skill/Scrapling-Skill/LICENSE.txt
new file mode 100644
index 0000000..41615aa
--- /dev/null
+++ b/agent-skill/Scrapling-Skill/LICENSE.txt
@@ -0,0 +1,28 @@
+BSD 3-Clause License
+
+Copyright (c) 2024, Karim shoair
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/agent-skill/Scrapling-Skill/SKILL.md b/agent-skill/Scrapling-Skill/SKILL.md
new file mode 100644
index 0000000..724e704
--- /dev/null
+++ b/agent-skill/Scrapling-Skill/SKILL.md
@@ -0,0 +1,359 @@
+---
+name: scrapling-official
+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.
+version: 0.4.2
+license: Complete terms in LICENSE.txt
+---
+
+# Scrapling
+
+Scrapling is an adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl.
+
+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.
+
+Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers for Web Scrapers and regular users, there's something for everyone.
+
+**Requires: Python 3.10+**
+
+**This is the official skill for the scrapling library by the library author.**
+
+
+## Setup (once)
+
+Create a virtual Python environment through any way available, like `venv`, then inside the environment do:
+
+`pip install "scrapling[all]>=0.4.2"`
+
+Then do this to download all the browsers' dependencies:
+
+```bash
+scrapling install --force
+```
+
+Make note of the `scrapling` binary path and use it instead of `scrapling` from now on with all commands (if `scrapling` is not on `$PATH`).
+
+### Docker
+Another option if the user doesn't have Python or doesn't want to use it is to use the Docker image, but this can be used only in the commands, so no writing Python code for scrapling this way:
+
+```bash
+docker pull pyd4vinci/scrapling
+```
+or
+```bash
+docker pull ghcr.io/d4vinci/scrapling:latest
+```
+
+## CLI Usage
+
+The `scrapling extract` command group lets you download and extract content from websites directly without writing any code.
+
+```bash
+Usage: scrapling extract [OPTIONS] COMMAND [ARGS]...
+
+Commands:
+ get Perform a GET request and save the content to a file.
+ post Perform a POST request and save the content to a file.
+ put Perform a PUT request and save the content to a file.
+ delete Perform a DELETE request and save the content to a file.
+ fetch Use a browser to fetch content with browser automation and flexible options.
+ stealthy-fetch Use a stealthy browser to fetch content with advanced stealth features.
+```
+
+### Usage pattern
+- Choose your output format by changing the file extension. Here are some examples for the `scrapling extract get` command:
+ - Convert the HTML content to Markdown, then save it to the file (great for documentation): `scrapling extract get "https://blog.example.com" article.md`
+ - Save the HTML content as it is to the file: `scrapling extract get "https://example.com" page.html`
+ - Save a clean version of the text content of the webpage to the file: `scrapling extract get "https://example.com" content.txt`
+- Output to a temp file, read it back, then clean up.
+- All commands can use CSS selectors to extract specific parts of the page through `--css-selector` or `-s`.
+
+Which command to use generally:
+- Use **`get`** with simple websites, blogs, or news articles.
+- Use **`fetch`** with modern web apps, or sites with dynamic content.
+- Use **`stealthy-fetch`** with protected sites, Cloudflare, or anti-bot systems.
+
+> When unsure, start with `get`. If it fails or returns empty content, escalate to `fetch`, then `stealthy-fetch`. The speed of `fetch` and `stealthy-fetch` is nearly the same, so you are not sacrificing anything.
+
+#### Key options (requests)
+
+Those options are shared between the 4 HTTP request commands:
+
+| Option | Input type | Description |
+|:-------------------------------------------|:----------:|:-----------------------------------------------------------------------------------------------------------------------------------------------|
+| -H, --headers | TEXT | HTTP headers in format "Key: Value" (can be used multiple times) |
+| --cookies | TEXT | Cookies string in format "name1=value1; name2=value2" |
+| --timeout | INTEGER | Request timeout in seconds (default: 30) |
+| --proxy | TEXT | Proxy URL in format "http://username:password@host:port" |
+| -s, --css-selector | TEXT | CSS selector to extract specific content from the page. It returns all matches. |
+| -p, --params | TEXT | Query parameters in format "key=value" (can be used multiple times) |
+| --follow-redirects / --no-follow-redirects | None | Whether to follow redirects (default: True) |
+| --verify / --no-verify | None | Whether to verify SSL certificates (default: True) |
+| --impersonate | TEXT | Browser to impersonate. Can be a single browser (e.g., Chrome) or a comma-separated list for random selection (e.g., Chrome, Firefox, Safari). |
+| --stealthy-headers / --no-stealthy-headers | None | Use stealthy browser headers (default: True) |
+
+Options shared between `post` and `put` only:
+
+| Option | Input type | Description |
+|:-----------|:----------:|:----------------------------------------------------------------------------------------|
+| -d, --data | TEXT | Form data to include in the request body (as string, ex: "param1=value1¶m2=value2") |
+| -j, --json | TEXT | JSON data to include in the request body (as string) |
+
+Examples:
+
+```bash
+# Basic download
+scrapling extract get "https://news.site.com" news.md
+
+# Download with custom timeout
+scrapling extract get "https://example.com" content.txt --timeout 60
+
+# Extract only specific content using CSS selectors
+scrapling extract get "https://blog.example.com" articles.md --css-selector "article"
+
+# Send a request with cookies
+scrapling extract get "https://scrapling.requestcatcher.com" content.md --cookies "session=abc123; user=john"
+
+# Add user agent
+scrapling extract get "https://api.site.com" data.json -H "User-Agent: MyBot 1.0"
+
+# Add multiple headers
+scrapling extract get "https://site.com" page.html -H "Accept: text/html" -H "Accept-Language: en-US"
+```
+
+#### Key options (browsers)
+
+Both (`fetch` / `stealthy-fetch`) share options:
+
+
+| Option | Input type | Description |
+|:-----------------------------------------|:----------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------|
+| --headless / --no-headless | None | Run browser in headless mode (default: True) |
+| --disable-resources / --enable-resources | None | Drop unnecessary resources for speed boost (default: False) |
+| --network-idle / --no-network-idle | None | Wait for network idle (default: False) |
+| --real-chrome / --no-real-chrome | None | If you have a Chrome browser installed on your device, enable this, and the Fetcher will launch an instance of your browser and use it. (default: False) |
+| --timeout | INTEGER | Timeout in milliseconds (default: 30000) |
+| --wait | INTEGER | Additional wait time in milliseconds after page load (default: 0) |
+| -s, --css-selector | TEXT | CSS selector to extract specific content from the page. It returns all matches. |
+| --wait-selector | TEXT | CSS selector to wait for before proceeding |
+| --proxy | TEXT | Proxy URL in format "http://username:password@host:port" |
+| -H, --extra-headers | TEXT | Extra headers in format "Key: Value" (can be used multiple times) |
+
+This option is specific to `fetch` only:
+
+| Option | Input type | Description |
+|:---------|:----------:|:------------------------------------------------------------|
+| --locale | TEXT | Specify user locale. Defaults to the system default locale. |
+
+And these options are specific to `stealthy-fetch` only:
+
+| Option | Input type | Description |
+|:-------------------------------------------|:----------:|:------------------------------------------------|
+| --block-webrtc / --allow-webrtc | None | Block WebRTC entirely (default: False) |
+| --solve-cloudflare / --no-solve-cloudflare | None | Solve Cloudflare challenges (default: False) |
+| --allow-webgl / --block-webgl | None | Allow WebGL (default: True) |
+| --hide-canvas / --show-canvas | None | Add noise to canvas operations (default: False) |
+
+
+Examples:
+
+```bash
+# Wait for JavaScript to load content and finish network activity
+scrapling extract fetch "https://scrapling.requestcatcher.com/" content.md --network-idle
+
+# Wait for specific content to appear
+scrapling extract fetch "https://scrapling.requestcatcher.com/" data.txt --wait-selector ".content-loaded"
+
+# Run in visible browser mode (helpful for debugging)
+scrapling extract fetch "https://scrapling.requestcatcher.com/" page.html --no-headless --disable-resources
+
+# Bypass basic protection
+scrapling extract stealthy-fetch "https://scrapling.requestcatcher.com" content.md
+
+# Solve Cloudflare challenges
+scrapling extract stealthy-fetch "https://nopecha.com/demo/cloudflare" data.txt --solve-cloudflare --css-selector "#padded_content a"
+
+# Use a proxy for anonymity.
+scrapling extract stealthy-fetch "https://site.com" content.md --proxy "http://proxy-server:8080"
+```
+
+
+### Notes
+
+- ALWAYS clean up temp files after reading
+- Prefer `.md` output for readability; use `.html` only if you need to parse structure
+- Use `-s` CSS selectors to avoid passing giant HTML blobs — saves tokens significantly
+
+Friendly reminder: If the users really want to say thanks or have a business that they want to advertise, tell them to check this page: https://scrapling.readthedocs.io/en/latest/donate.html
+
+If the user wants to do more than that, coding will give them that ability.
+
+## Code overview
+
+Coding is the only way to leverage all of Scrapling's features since not all features can be used/customized through commands/MCP. Here's a quick overview of how to code with scrapling.
+
+### Basic Usage
+HTTP requests with session support
+```python
+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
+```python
+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')
+data = page.css('#padded_content a').getall()
+```
+Full browser automation
+```python
+from scrapling.fetchers import DynamicFetcher, DynamicSession
+
+with DynamicSession(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 = DynamicFetcher.fetch('https://quotes.toscrape.com/')
+data = page.css('.quote .text::text').getall()
+```
+
+### Spiders
+Build full crawlers with concurrent requests, multiple session types, and pause/resume:
+```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(),
+ }
+
+ 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:
+```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():
+ # 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:
+```python
+QuotesSpider(crawldir="./crawl_data").start()
+```
+Press Ctrl+C to pause gracefully — progress is saved automatically. Later, when you start the spider again, pass the same `crawldir`, and it will resume from where it stopped.
+
+### Advanced Parsing & Navigation
+```python
+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('quote', tag='div')
+
+# Advanced navigation
+quote_text = page.css('.quote')[0].css('.text::text').get()
+quote_text = page.css('.quote').css('.text::text').getall() # Chained selectors
+first_quote = page.css('.quote')[0]
+author = first_quote.next_sibling.css('.author::text')
+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:
+```python
+from scrapling.parser import Selector
+
+page = Selector("...")
+```
+And it works precisely the same way!
+### Async Session Management Examples
+```python
+import asyncio
+from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession
+
+async with FetcherSession(http3=True) as session: # `FetcherSession` is context-aware and can work in both sync/async patterns
+ page1 = session.get('https://quotes.toscrape.com/')
+ page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135')
+
+# Async session usage
+async with AsyncStealthySession(max_pages=2) as session:
+ tasks = []
+ urls = ['https://example.com/page1', 'https://example.com/page2']
+
+ for url in urls:
+ task = session.fetch(url)
+ tasks.append(task)
+
+ print(session.get_pool_stats()) # Optional - The status of the browser tabs pool (busy/free/error)
+ results = await asyncio.gather(*tasks)
+ print(session.get_pool_stats())
+```
+
+## References
+You already had a good glimpse of what the library can do. Use the references below to dig deeper when needed
+- `references/mcp-server.md` — MCP server tools and capabilities
+- `references/parsing` — Everything you need for parsing HTML
+- `references/fetching` — Everything you need to fetch websites and session persistence
+- `references/spiders` — Everything you need to write spiders, proxy rotation, and advanced features. It follows a Scrapy-like format
+- `references/migrating_from_beautifulsoup.md` — A quick API comparison between scrapling and Beautifulsoup
+- `https://github.com/D4Vinci/Scrapling/tree/main/docs` — Full official docs in Markdown for quick access (use only if current references do not look up-to-date).
+
+This skill encapsulates almost all the published documentation in Markdown, so don't check external sources or search online without the user's permission.
+
+## Guardrails (Always)
+- Only scrape content you're authorized to access.
+- Respect robots.txt and ToS.
+- Add delays (download_delay) for large crawls.
+- Don't bypass paywalls or authentication without permission.
+- Never scrape personal/sensitive data.
\ No newline at end of file
diff --git a/agent-skill/Scrapling-Skill/examples/01_fetcher_session.py b/agent-skill/Scrapling-Skill/examples/01_fetcher_session.py
new file mode 100644
index 0000000..f2d5e1e
--- /dev/null
+++ b/agent-skill/Scrapling-Skill/examples/01_fetcher_session.py
@@ -0,0 +1,26 @@
+"""
+Example 1: Python - FetcherSession (persistent HTTP session with Chrome TLS fingerprint)
+
+Scrapes all 10 pages of quotes.toscrape.com using a single HTTP session.
+No browser launched — fast and lightweight.
+
+Best for: static or semi-static sites, APIs, pages that don't require JavaScript.
+"""
+
+from scrapling.fetchers import FetcherSession
+
+all_quotes = []
+
+with FetcherSession(impersonate="chrome") as session:
+ for i in range(1, 11):
+ page = session.get(
+ f"https://quotes.toscrape.com/page/{i}/",
+ stealthy_headers=True,
+ )
+ quotes = page.css(".quote .text::text").getall()
+ all_quotes.extend(quotes)
+ print(f"Page {i}: {len(quotes)} quotes (status {page.status})")
+
+print(f"\nTotal: {len(all_quotes)} quotes\n")
+for i, quote in enumerate(all_quotes, 1):
+ print(f"{i:>3}. {quote}")
diff --git a/agent-skill/Scrapling-Skill/examples/02_dynamic_session.py b/agent-skill/Scrapling-Skill/examples/02_dynamic_session.py
new file mode 100644
index 0000000..64229fe
--- /dev/null
+++ b/agent-skill/Scrapling-Skill/examples/02_dynamic_session.py
@@ -0,0 +1,26 @@
+"""
+Example 2: Python - DynamicSession (Playwright browser automation, visible)
+
+Scrapes all 10 pages of quotes.toscrape.com using a persistent browser session.
+The browser window stays open across all page requests for efficiency.
+
+Best for: JavaScript-heavy pages, SPAs, sites with dynamic content loading.
+
+Set headless=True to run the browser hidden.
+Set disable_resources=True to skip loading images/fonts for a speed boost.
+"""
+
+from scrapling.fetchers import DynamicSession
+
+all_quotes = []
+
+with DynamicSession(headless=False, disable_resources=True) as session:
+ for i in range(1, 11):
+ page = session.fetch(f"https://quotes.toscrape.com/page/{i}/")
+ quotes = page.css(".quote .text::text").getall()
+ all_quotes.extend(quotes)
+ print(f"Page {i}: {len(quotes)} quotes (status {page.status})")
+
+print(f"\nTotal: {len(all_quotes)} quotes\n")
+for i, quote in enumerate(all_quotes, 1):
+ print(f"{i:>3}. {quote}")
diff --git a/agent-skill/Scrapling-Skill/examples/03_stealthy_session.py b/agent-skill/Scrapling-Skill/examples/03_stealthy_session.py
new file mode 100644
index 0000000..c3c68eb
--- /dev/null
+++ b/agent-skill/Scrapling-Skill/examples/03_stealthy_session.py
@@ -0,0 +1,26 @@
+"""
+Example 3: Python - StealthySession (Patchright stealth browser, visible)
+
+Scrapes all 10 pages of quotes.toscrape.com using a persistent stealth browser session.
+Bypasses anti-bot protections automatically (Cloudflare Turnstile, fingerprinting, etc.).
+
+Best for: well-protected sites, Cloudflare-gated pages, sites that detect Playwright.
+
+Set headless=True to run the browser hidden.
+Add solve_cloudflare=True to auto-solve Cloudflare challenges.
+"""
+
+from scrapling.fetchers import StealthySession
+
+all_quotes = []
+
+with StealthySession(headless=False) as session:
+ for i in range(1, 11):
+ page = session.fetch(f"https://quotes.toscrape.com/page/{i}/")
+ quotes = page.css(".quote .text::text").getall()
+ all_quotes.extend(quotes)
+ print(f"Page {i}: {len(quotes)} quotes (status {page.status})")
+
+print(f"\nTotal: {len(all_quotes)} quotes\n")
+for i, quote in enumerate(all_quotes, 1):
+ print(f"{i:>3}. {quote}")
diff --git a/agent-skill/Scrapling-Skill/examples/04_spider.py b/agent-skill/Scrapling-Skill/examples/04_spider.py
new file mode 100644
index 0000000..c464007
--- /dev/null
+++ b/agent-skill/Scrapling-Skill/examples/04_spider.py
@@ -0,0 +1,58 @@
+"""
+Example 4: Python - Spider (auto-crawling framework)
+
+Scrapes ALL pages of quotes.toscrape.com by following "Next" pagination links
+automatically. No manual page looping needed.
+
+The spider yields structured items (text + author + tags) and exports them to JSON.
+
+Best for: multi-page crawls, full-site scraping, anything needing pagination or
+link following across many pages.
+
+Outputs:
+ - Live stats to terminal during crawl
+ - Final crawl stats at the end
+ - quotes.json in the current directory
+"""
+
+from scrapling.spiders import Spider, Response
+
+
+class QuotesSpider(Spider):
+ name = "quotes"
+ start_urls = ["https://quotes.toscrape.com/"]
+ concurrent_requests = 5 # Fetch up to 5 pages at once
+
+ async def parse(self, response: Response):
+ # Extract all quotes on the current page
+ for quote in response.css(".quote"):
+ yield {
+ "text": quote.css(".text::text").get(),
+ "author": quote.css(".author::text").get(),
+ "tags": quote.css(".tags .tag::text").getall(),
+ }
+
+ # Follow the "Next" button to the next page (if it exists)
+ next_page = response.css(".next a")
+ if next_page:
+ yield response.follow(next_page[0].attrib["href"])
+
+
+if __name__ == "__main__":
+ result = QuotesSpider().start()
+
+ print(f"\n{'=' * 50}")
+ print(f"Scraped : {result.stats.items_scraped} quotes")
+ print(f"Requests: {result.stats.requests_count}")
+ print(f"Time : {result.stats.elapsed_seconds:.2f}s")
+ print(f"Speed : {result.stats.requests_per_second:.2f} req/s")
+ print(f"{'=' * 50}\n")
+
+ for i, item in enumerate(result.items, 1):
+ print(f"{i:>3}. [{item['author']}] {item['text']}")
+ if item["tags"]:
+ print(f" Tags: {', '.join(item['tags'])}")
+
+ # Export to JSON
+ result.items.to_json("quotes.json", indent=True)
+ print("\nExported to quotes.json")
diff --git a/agent-skill/Scrapling-Skill/examples/README.md b/agent-skill/Scrapling-Skill/examples/README.md
new file mode 100644
index 0000000..dfc65e4
--- /dev/null
+++ b/agent-skill/Scrapling-Skill/examples/README.md
@@ -0,0 +1,45 @@
+# Scrapling Examples
+
+These examples scrape [quotes.toscrape.com](https://quotes.toscrape.com) — a safe, purpose-built scraping sandbox — and demonstrate every tool available in Scrapling, from plain HTTP to full browser automation and spiders.
+
+All examples collect **all 100 quotes across 10 pages**.
+
+## Quick Start
+
+Make sure Scrapling is installed:
+
+```bash
+pip install "scrapling[all]>=0.4.2"
+scrapling install --force
+```
+
+## Examples
+
+| File | Tool | Type | Best For |
+|--------------------------|-------------------|-----------------------------|---------------------------------------|
+| `01_fetcher_session.py` | `FetcherSession` | Python — persistent HTTP | APIs, fast multi-page scraping |
+| `02_dynamic_session.py` | `DynamicSession` | Python — browser automation | Dynamic/SPA pages |
+| `03_stealthy_session.py` | `StealthySession` | Python — stealth browser | Cloudflare, fingerprint bypass |
+| `04_spider.py` | `Spider` | Python — auto-crawling | Multi-page crawls, full-site scraping |
+
+## Running
+
+**Python scripts:**
+
+```bash
+python examples/01_fetcher_session.py
+python examples/02_dynamic_session.py # Opens a visible browser
+python examples/03_stealthy_session.py # Opens a visible stealth browser
+python examples/04_spider.py # Auto-crawls all pages, exports quotes.json
+```
+
+## Escalation Guide
+
+Start with the fastest, lightest option and escalate only if needed:
+
+```
+get / FetcherSession
+ └─ If JS required → fetch / DynamicSession
+ └─ If blocked → stealthy-fetch / StealthySession
+ └─ If multi-page → Spider
+```
diff --git a/agent-skill/Scrapling-Skill/references/fetching/choosing.md b/agent-skill/Scrapling-Skill/references/fetching/choosing.md
new file mode 100644
index 0000000..974b566
--- /dev/null
+++ b/agent-skill/Scrapling-Skill/references/fetching/choosing.md
@@ -0,0 +1,77 @@
+# Fetchers basics
+
+## Introduction
+Fetchers are classes that do requests or fetch pages in a single-line fashion with many features and return a [Response](#response-object) object. All fetchers have separate session classes to keep the session running (e.g., a browser fetcher keeps the browser open until you finish all requests).
+
+Fetchers are not wrappers built on top of other libraries. They use these libraries as an engine to request/fetch pages but add features the underlying engines don't have, while still fully leveraging and optimizing them for web scraping.
+
+## Fetchers Overview
+
+Scrapling provides three different fetcher classes with their session classes; each fetcher is designed for a specific use case.
+
+The following table compares them and can be quickly used for guidance.
+
+
+| Feature | Fetcher | DynamicFetcher | StealthyFetcher |
+|--------------------|---------------------------------------------------|-----------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
+| Relative speed | 🐇🐇🐇🐇🐇 | 🐇🐇🐇 | 🐇🐇🐇 |
+| Stealth | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
+| Anti-Bot options | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
+| JavaScript loading | ❌ | ✅ | ✅ |
+| Memory Usage | ⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
+| Best used for | Basic scraping when HTTP requests alone can do it | - Dynamically loaded websites Description 1
+Description 2
+Description 1
+Description 2
+This is product 1
+ $10.99 +This is product 2
+ $20.99 +This is product 3
+ $15.99 +This is product 1
\n $10.99\nThis is product 1
+ $10.99 +{"some_key": "some_value"}
' + ``` + The `json` method can be used directly: + ```python + >>> page.json() + {'some_key': 'some_value'} + ``` + For JSON responses, the [Selector](#selector) class keeps a raw copy of the content it receives. When `.json()` is called, it checks for that raw copy first and converts it to JSON. If the raw copy is unavailable (as with sub-elements), it checks the current element's text content, then falls back to `get_all_text`. + +- The `.clean()` method removes all whitespace and consecutive spaces, returning a new `TextHandler` instance: +```python +>>> TextHandler('\n wonderful idea, \reh?').clean() +'wonderful idea, eh?' +``` +The `remove_entities` argument causes `clean` to replace HTML entities with their corresponding characters. + +- The `.sort()` method sorts the string characters: +```python +>>> TextHandler('acb').sort() +'abc' +``` +Or do it in reverse: +```python +>>> TextHandler('acb').sort(reverse=True) +'cba' +``` + +This class is returned in place of strings nearly everywhere in the library. + +## TextHandlers +This class inherits from standard lists, adding `re` and `re_first` as new methods. + +The `re_first` method runs `re` on each [TextHandler](#texthandler) and returns the first result, or `None`. + +## AttributesHandler +This is a read-only version of Python's standard dictionary, or `dict`, used solely to store the attributes of each element/[Selector](#selector) instance. +```python +>>> print(page.find('script').attrib) +{'id': 'page-data', 'type': 'application/json'} +>>> type(page.find('script').attrib).__name__ +'AttributesHandler' +``` +Because it's read-only, it will use fewer resources than the standard dictionary. Still, it has the same dictionary method and properties, except those that allow you to modify/override the data. + +It currently adds two extra simple methods: + +- The `search_values` method + + Searches the current attributes by values (rather than keys) and returns a dictionary of each matching item. + + A simple example would be + ```python + >>> for i in page.find('script').attrib.search_values('page-data'): + print(i) + {'id': 'page-data'} + ``` + But this method provides the `partial` argument as well, which allows you to search by part of the value: + ```python + >>> for i in page.find('script').attrib.search_values('page', partial=True): + print(i) + {'id': 'page-data'} + ``` + A more practical example is using it with `find_all` to find all elements that have a specific value in their attributes: + ```python + >>> page.find_all(lambda element: list(element.attrib.search_values('product'))) + [£51.77
' parent='£51.77
' parent='£53.74
' parent='£50.10
' parent='£47.82
' parent=',
+ ,
+ ,
+...]
+```
+The number of elements is 19, not 20, because the current element is not included in the results:
+```python
+>>> len(element.find_similar(ignore_attributes=['title']))
+19
+```
+Get the `href` attribute from all similar elements
+```python
+>>> [
+ element.attrib['href']
+ for element in element.find_similar(ignore_attributes=['title'])
+]
+['catalogue/a-light-in-the-attic_1000/index.html',
+ 'catalogue/soumission_998/index.html',
+ 'catalogue/sharp-objects_997/index.html',
+ ...]
+```
+Getting all books' data using that element as a starting point:
+```python
+>>> for product in element.parent.parent.find_similar():
+ print({
+ "name": product.css('h3 a::text').get(),
+ "price": product.css('.price_color')[0].re_first(r'[\d\.]+'),
+ "stock": product.css('.availability::text').getall()[-1].clean()
+ })
+{'name': 'A Light in the ...', 'price': '51.77', 'stock': 'In stock'}
+{'name': 'Soumission', 'price': '50.10', 'stock': 'In stock'}
+{'name': 'Sharp Objects', 'price': '47.82', 'stock': 'In stock'}
+...
+```
+### Advanced examples
+Advanced examples using the `find_similar` method:
+
+E-commerce Product Extraction
+```python
+def extract_product_grid(page):
+ # Find the first product card
+ first_product = page.find_by_text('Add to Cart').find_ancestor(
+ lambda e: e.has_class('product-card')
+ )
+
+ # Find similar product cards
+ products = first_product.find_similar()
+
+ return [
+ {
+ 'name': p.css('h3::text').get(),
+ 'price': p.css('.price::text').re_first(r'\d+\.\d{2}'),
+ 'stock': 'In stock' in p.text,
+ 'rating': p.css('.rating')[0].attrib.get('data-rating')
+ }
+ for p in products
+ ]
+```
+Table Row Extraction
+```python
+def extract_table_data(page):
+ # Find the first data row
+ first_row = page.css('table tbody tr')[0]
+
+ # Find similar rows
+ rows = first_row.find_similar()
+
+ return [
+ {
+ 'column1': row.css('td:nth-child(1)::text').get(),
+ 'column2': row.css('td:nth-child(2)::text').get(),
+ 'column3': row.css('td:nth-child(3)::text').get()
+ }
+ for row in rows
+ ]
+```
+Form Field Extraction
+```python
+def extract_form_fields(page):
+ # Find first form field container
+ first_field = page.css('input')[0].find_ancestor(
+ lambda e: e.has_class('form-field')
+ )
+
+ # Find similar field containers
+ fields = first_field.find_similar()
+
+ return [
+ {
+ 'label': f.css('label::text').get(),
+ 'type': f.css('input')[0].attrib.get('type'),
+ 'required': 'required' in f.css('input')[0].attrib
+ }
+ for f in fields
+ ]
+```
+Extracting reviews from a website
+```python
+def extract_reviews(page):
+ # Find first review
+ first_review = page.find_by_text('Great product!')
+ review_container = first_review.find_ancestor(
+ lambda e: e.has_class('review')
+ )
+
+ # Find similar reviews
+ all_reviews = review_container.find_similar()
+
+ return [
+ {
+ 'text': r.css('.review-text::text').get(),
+ 'rating': r.attrib.get('data-rating'),
+ 'author': r.css('.reviewer::text').get()
+ }
+ for r in all_reviews
+ ]
+```
+## Filters-based searching
+Inspired by BeautifulSoup's `find_all` function, elements can be found using the `find_all` and `find` methods. Both methods accept multiple filters and return all elements on the pages where all filters apply.
+
+To be more specific:
+
+* Any string passed is considered a tag name.
+* Any iterable passed, like List/Tuple/Set, will be considered as an iterable of tag names.
+* Any dictionary is considered a mapping of HTML element(s), attribute names, and attribute values.
+* Any regex patterns passed are used to filter elements by content, like the `find_by_regex` method
+* Any functions passed are used to filter elements
+* Any keyword argument passed is considered as an HTML element attribute with its value.
+
+It collects all passed arguments and keywords, and each filter passes its results to the following filter in a waterfall-like filtering system.
+
+It filters all elements in the current page/element in the following order:
+
+1. All elements with the passed tag name(s) get collected.
+2. All elements that match all passed attribute(s) are collected; if a previous filter is used, then previously collected elements are filtered.
+3. All elements that match all passed regex patterns are collected, or if previous filter(s) are used, then previously collected elements are filtered.
+4. All elements that fulfill all passed function(s) are collected; if a previous filter(s) is used, then previously collected elements are filtered.
+
+**Notes:**
+
+1. The filtering process always starts from the first filter it finds in the filtering order above. If no tag name(s) are passed but attributes are passed, the process starts from step 2, and so on.
+2. The order in which arguments are passed does not matter. The only order considered is the one explained above.
+
+### Examples
+```python
+>>> from scrapling.fetchers import Fetcher
+>>> page = Fetcher.get('https://quotes.toscrape.com/')
+```
+Find all elements with the tag name `div`.
+```python
+>>> page.find_all('div')
+[
+
+
+ 선택 메서드
+ ·
+ Fetcher 선택 가이드
+ ·
+ Spider
+ ·
+ 프록시 로테이션
+ ·
+ CLI
+ ·
+ MCP 서버
+
+
+
-
-
+
+
+
+
+
@@ -84,46 +87,67 @@ MySpider().start()
-
-
-
- جوالب Scrapling تتعامل مع Cloudflare Turnstile، لكن للحماية على مستوى المؤسسات، توفر Hyper Solutions نقاط نهاية API تولّد رموز antibot صالحة لـ:
+
Akamai • DataDome • Kasada • Incapsula
-
بدون أتمتة متصفح. استدعاءات API بسيطة تُرجع الكوكيز والرؤوس الدقيقة التي تتطلبها هذه الأنظمة.
🚀
- اشترك
- | 💬
- Discord
Scrapling يتعامل مع Cloudflare Turnstile. للحماية على مستوى المؤسسات، توفر
+ Hyper Solutions
+ نقاط نهاية API تولّد رموز antibot صالحة لـ Akamai، DataDome، Kasada و Incapsula. استدعاءات API بسيطة، بدون أتمتة متصفح.
-
-
مرحباً، لقد بنينا BirdProxies لأن البروكسيات لا يجب أن تكون معقدة أو باهظة الثمن.
بروكسيات سكنية و ISP سريعة في أكثر من 195 موقعاً، أسعار عادلة، ودعم حقيقي.
+ مرحباً، لقد بنينا
+ BirdProxies
+ لأن البروكسيات لا يجب أن تكون معقدة أو باهظة الثمن.
بروكسيات سكنية و ISP سريعة في أكثر من 195 موقعاً، أسعار عادلة، ودعم حقيقي.
جرّب لعبة FlappyBird على صفحة الهبوط للحصول على بيانات مجانية!
-
🚀
- جرّب الآن
- | 💬
- Discord
-
+
-
-
Evomi: بروكسيات سكنية بدءاً من 0.49$/جيجابايت. متصفح سكرابينج مع Chromium مُزيّف بالكامل، عناوين IP سكنية، حل تلقائي لـ CAPTCHA، وتجاوز أنظمة مكافحة البوتات.
+
+
+ Evomi
+ : بروكسيات سكنية بدءاً من 0.49$/جيجابايت. متصفح سكرابينج مع Chromium مُزيّف بالكامل، عناوين IP سكنية، حل تلقائي لـ CAPTCHA، وتجاوز أنظمة مكافحة البوتات.
واجهة Scraper API لنتائج بدون عناء. تكاملات MCP و N8N متاحة.
-
+
🚀
- جرّب الآن
+
+
+
+
+
+
+ TikHub.io يوفر أكثر من 900 واجهة API مستقرة عبر أكثر من 16 منصة تشمل TikTok و X و YouTube و Instagram، مع أكثر من 40 مليون مجموعة بيانات.
+
يقدم أيضاً نماذج ذكاء اصطناعي بأسعار مخفضة — Claude و GPT و GEMINI والمزيد بخصم يصل إلى 71%.
+
+
+
+
+
+
+
+
+ Nsocks يوفر بروكسيات سكنية و ISP سريعة للمطورين والسكرابرز. تغطية IP عالمية، إخفاء هوية عالي، تدوير ذكي، وأداء موثوق للأتمتة واستخراج البيانات. استخدم Xcrawl لتبسيط زحف الويب على نطاق واسع.
+
+
+
@@ -132,15 +156,10 @@ MySpider().start()
-
+
+
+
+
+
+ أغلق حاسوبك. أدوات الكشط تواصل العمل.
+ PetroSky VPS - خوادم سحابية مصممة للأتمتة المتواصلة. أجهزة Windows وLinux مع تحكم كامل. بدءًا من 6.99 يورو/شهريًا.
+
-
-
-
-
-
+
diff --git a/docs/README_CN.md b/docs/README_CN.md
index 0a56753..ae9206a 100644
--- a/docs/README_CN.md
+++ b/docs/README_CN.md
@@ -16,8 +16,11 @@
-
-
+
+
+
+
+
@@ -84,47 +87,67 @@ MySpider().start()
-
-
-
- Scrapling 的 fetcher 可以处理 Cloudflare Turnstile,但对于企业级保护,Hyper Solutions 提供生成有效 antibot 令牌的 API 端点,支持:
+
Akamai • DataDome • Kasada • Incapsula
-
无需浏览器自动化。简单的 API 调用即可返回这些系统所需的确切 cookie 和请求头。
-
🚀
- 订阅
- | 💬
- Discord
Scrapling 可处理 Cloudflare Turnstile。对于企业级保护,
+ Hyper Solutions
+ 提供 API 端点,生成适用于 Akamai、DataDome、Kasada 和 Incapsula 的有效 antibot 令牌。简单的 API 调用,无需浏览器自动化。
-
-
嘿,我们创建了 BirdProxies,因为代理不应该复杂或昂贵。
覆盖 195+ 地区的快速住宅和 ISP 代理,公平定价,真正的支持。
+ 嘿,我们创建了
+ BirdProxies
+ ,因为代理不应该复杂或昂贵。
覆盖 195+ 地区的快速住宅和 ISP 代理,公平定价,真正的支持。
在落地页试试我们的 FlappyBird 游戏,获取免费流量!
-
🚀
- 立即试用
- | 💬
- Discord
-
+
-
-
Evomi:住宅代理低至 0.49 美元/GB。具备完全伪装 Chromium 的爬虫浏览器、住宅 IP、自动验证码解决和反机器人绕过。
+
+
+ Evomi
+ :住宅代理低至 0.49 美元/GB。具备完全伪装 Chromium 的爬虫浏览器、住宅 IP、自动验证码解决和反机器人绕过。
Scraper API 轻松获取结果。支持 MCP 和 N8N 集成。
-
+
🚀
- 立即试用
+
+
+
+
+
+
+ TikHub.io 提供覆盖 16+ 平台(包括 TikTok、X、YouTube 和 Instagram)的 900+ 稳定 API,拥有 4000 万+ 数据集。
+
还提供优惠 AI 模型 — Claude、GPT、GEMINI 等,最高优惠 71%。
+
+
+
+
+
+
+
+
+ Nsocks 提供面向开发者和爬虫的快速住宅和 ISP 代理。全球 IP 覆盖、高匿名性、智能轮换,以及可靠的自动化和数据提取性能。使用 Xcrawl 简化大规模网页爬取。
+
+
+
@@ -133,15 +156,10 @@ MySpider().start()
-
+
+
+
+
+
+ 合上笔记本电脑,您的爬虫仍在运行。
+ PetroSky VPS - 为不间断自动化而生的云服务器。Windows 和 Linux 系统,完全掌控。低至 €6.99/月。
+
-
-
-
-
-
+
diff --git a/docs/README_DE.md b/docs/README_DE.md
index 2f5a889..17fcef6 100644
--- a/docs/README_DE.md
+++ b/docs/README_DE.md
@@ -16,8 +16,11 @@
-
-
+
+
+
+
+
@@ -84,47 +87,67 @@ MySpider().start()
-
-
-
- Scraplings Fetcher bewältigen Cloudflare Turnstile, aber für Schutz auf Unternehmensebene bietet Hyper Solutions API-Endpunkte, die gültige Antibot-Tokens generieren für:
+
Akamai • DataDome • Kasada • Incapsula
-
Keine Browser-Automatisierung. Einfache API-Aufrufe, die genau die Cookies und Header zurückgeben, die diese Systeme erfordern.
-
🚀
- Abonnieren
- | 💬
- Discord
Scrapling bewältigt Cloudflare Turnstile. Für Schutz auf Unternehmensebene bietet
+ Hyper Solutions
+ API-Endpunkte, die gültige Antibot-Tokens für Akamai, DataDome, Kasada und Incapsula generieren. Einfache API-Aufrufe, keine Browser-Automatisierung nötig.
-
-
Hey, wir haben BirdProxies gebaut, weil Proxies nicht kompliziert oder überteuert sein sollten.
Schnelle Residential- und ISP-Proxies in über 195 Standorten, faire Preise und echter Support.
+ Hey, wir haben
+ BirdProxies
+ gebaut, weil Proxies nicht kompliziert oder überteuert sein sollten.
Schnelle Residential- und ISP-Proxies in über 195 Standorten, faire Preise und echter Support.
Probieren Sie unser FlappyBird-Spiel auf der Landingpage für kostenlose Daten!
-
🚀
- Jetzt testen
- | 💬
- Discord
-
+
-
-
Evomi: Residential-Proxies ab 0,49 $/GB. Scraping-Browser mit vollständig gefälschtem Chromium, Residential-IPs, automatischer CAPTCHA-Lösung und Anti-Bot-Umgehung.
+
+
+ Evomi
+ : Residential-Proxies ab 0,49 $/GB. Scraping-Browser mit vollständig gefälschtem Chromium, Residential-IPs, automatischer CAPTCHA-Lösung und Anti-Bot-Umgehung.
Scraper-API für problemlose Ergebnisse. MCP- und N8N-Integrationen verfügbar.
-
+
🚀
- Jetzt testen
+
+
+
+
+
+
+ TikHub.io bietet über 900 stabile APIs auf mehr als 16 Plattformen, darunter TikTok, X, YouTube und Instagram, mit über 40 Mio. Datensätzen.
+
Bietet außerdem vergünstigte KI-Modelle — Claude, GPT, GEMINI und mehr mit bis zu 71% Rabatt.
+
+
+
+
+
+
+
+
+ Nsocks bietet schnelle Residential- und ISP-Proxies für Entwickler und Scraper. Globale IP-Abdeckung, hohe Anonymität, intelligente Rotation und zuverlässige Leistung für Automatisierung und Datenextraktion. Verwenden Sie Xcrawl, um großflächiges Web-Crawling zu vereinfachen.
+
+
+
@@ -133,15 +156,10 @@ MySpider().start()
-
+
+
+
+
+
+ Klappe den Laptop zu. Deine Scraper laufen weiter.
+ PetroSky VPS - Cloud-Server für ununterbrochene Automatisierung. Windows- und Linux-Maschinen mit voller Kontrolle. Ab €6,99/Monat.
+
-
-
-
-
-
+
diff --git a/docs/README_ES.md b/docs/README_ES.md
index a6c005b..9441c03 100644
--- a/docs/README_ES.md
+++ b/docs/README_ES.md
@@ -16,8 +16,11 @@
-
-
+
+
+
+
+
@@ -84,47 +87,67 @@ MySpider().start()
-
-
-
- Los fetchers de Scrapling manejan Cloudflare Turnstile, pero para protección de nivel empresarial, Hyper Solutions proporciona endpoints API que generan tokens antibot válidos para:
+
Akamai • DataDome • Kasada • Incapsula
-
Sin automatización de navegador. Simples llamadas API que devuelven las cookies y cabeceras exactas que estos sistemas requieren.
-
🚀
- Suscribirse
- | 💬
- Discord
Scrapling maneja Cloudflare Turnstile. Para protección de nivel empresarial,
+ Hyper Solutions
+ proporciona endpoints API que generan tokens antibot válidos para Akamai, DataDome, Kasada e Incapsula. Simples llamadas API, sin automatización de navegador.
-
-
Oye, creamos BirdProxies porque los proxies no deberían ser complicados ni caros.
Proxies residenciales e ISP rápidos en más de 195 ubicaciones, precios justos y soporte real.
+ Oye, creamos
+ BirdProxies
+ porque los proxies no deberían ser complicados ni caros.
Proxies residenciales e ISP rápidos en más de 195 ubicaciones, precios justos y soporte real.
¡Prueba nuestro juego FlappyBird en la página de inicio para obtener datos gratis!
-
🚀
- Probar ahora
- | 💬
- Discord
-
+
-
-
Evomi: proxies residenciales desde 0,49 $/GB. Navegador de scraping con Chromium totalmente falsificado, IPs residenciales, resolución automática de CAPTCHA y evasión anti-bot.
+
+
+ Evomi
+ : proxies residenciales desde 0,49 $/GB. Navegador de scraping con Chromium totalmente falsificado, IPs residenciales, resolución automática de CAPTCHA y evasión anti-bot.
API Scraper para resultados sin complicaciones. Integraciones MCP y N8N disponibles.
-
+
🚀
- Probar ahora
+
+
+
+
+
+
+ TikHub.io ofrece más de 900 APIs estables en más de 16 plataformas, incluyendo TikTok, X, YouTube e Instagram, con más de 40M de conjuntos de datos.
+
También ofrece modelos de IA con descuento — Claude, GPT, GEMINI y más con hasta un 71% de descuento.
+
+
+
+
+
+
+
+
+ Nsocks ofrece proxies residenciales e ISP rápidos para desarrolladores y scrapers. Cobertura IP global, alto anonimato, rotación inteligente y rendimiento fiable para automatización y extracción de datos. Usa Xcrawl para simplificar el crawling web a gran escala.
+
+
+
@@ -133,15 +156,10 @@ MySpider().start()
-
+
+
+
+
+
+ Cierra tu portátil. Tus scrapers siguen funcionando.
+ PetroSky VPS - servidores en la nube diseñados para automatización ininterrumpida. Máquinas Windows y Linux con control total. Desde €6,99/mes.
+
-
-
-
-
-
+
diff --git a/docs/README_FR.md b/docs/README_FR.md
index 6ec6205..9f8146f 100644
--- a/docs/README_FR.md
+++ b/docs/README_FR.md
@@ -16,8 +16,11 @@
-
-
+
+
+
+
+
@@ -84,46 +87,67 @@ MySpider().start()
-
-
-
- Les fetchers de Scrapling gèrent Cloudflare Turnstile, mais pour une protection de niveau entreprise, Hyper Solutions fournit des points d'accès API qui génèrent des tokens antibot valides pour :
+
Akamai • DataDome • Kasada • Incapsula
-
Pas d'automatisation de navigateur. De simples appels API retournant exactement les cookies et headers requis par ces systèmes.
🚀
- S'abonner
- | 💬
- Discord
Scrapling gère Cloudflare Turnstile. Pour une protection de niveau entreprise,
+ Hyper Solutions
+ fournit des endpoints API qui génèrent des tokens antibot valides pour Akamai, DataDome, Kasada et Incapsula. De simples appels API, sans automatisation de navigateur.
-
-
Nous avons créé BirdProxies parce que les proxies ne devraient pas être compliqués ni trop chers. Des proxies résidentiels et ISP rapides dans plus de 195 localisations, des prix équitables et un vrai support.
+ Nous avons créé
+ BirdProxies
+ parce que les proxies ne devraient pas être compliqués ni trop chers. Des proxies résidentiels et ISP rapides dans plus de 195 localisations, des prix équitables et un vrai support.
Essayez notre jeu FlappyBird sur la page d'accueil pour des données gratuites !
-
🚀
- Essayer maintenant
- | 💬
- Discord
-
+
-
-
Evomi : proxies résidentiels à partir de 0,49 $/Go. Navigateur de scraping avec Chromium entièrement falsifié, IPs résidentielles, résolution automatique de CAPTCHA et contournement anti-bot.
+
+
+ Evomi
+ : proxies résidentiels à partir de 0,49 $/Go. Navigateur de scraping avec Chromium entièrement falsifié, IPs résidentielles, résolution automatique de CAPTCHA et contournement anti-bot.
API Scraper pour des résultats sans tracas. Intégrations MCP et N8N disponibles.
-
+
🚀
- Essayer maintenant
+
+
+
+
+
+
+ TikHub.io propose plus de 900 APIs stables sur plus de 16 plateformes, dont TikTok, X, YouTube et Instagram, avec plus de 40M de jeux de données.
+
Propose également des modèles IA à prix réduit — Claude, GPT, GEMINI et plus, jusqu'à 71% de réduction.
+
+
+
+
+
+
+
+
+ Nsocks fournit des proxies résidentiels et ISP rapides pour les développeurs et les scrapeurs. Couverture IP mondiale, anonymat élevé, rotation intelligente et performances fiables pour l'automatisation et l'extraction de données. Utilisez Xcrawl pour simplifier le crawling web à grande échelle.
+
+
+
@@ -132,15 +156,10 @@ MySpider().start()
-
+
+
+
+
+
+ Fermez votre ordinateur. Vos scrapers continuent de tourner.
+ PetroSky VPS - des serveurs cloud conçus pour l'automatisation sans interruption. Machines Windows et Linux avec contrôle total. À partir de 6,99 €/mois.
+
-
-
-
-
-
+
diff --git a/docs/README_JP.md b/docs/README_JP.md
index 0fc3f9b..286919a 100644
--- a/docs/README_JP.md
+++ b/docs/README_JP.md
@@ -16,8 +16,11 @@
-
-
+
+
+
+
+
@@ -84,47 +87,67 @@ MySpider().start()
-
-
-
- ScraplingのfetcherはCloudflare Turnstileに対応していますが、エンタープライズレベルの保護には、Hyper Solutionsが有効なantibotトークンを生成するAPIエンドポイントを提供します:
+
Akamai • DataDome • Kasada • Incapsula
-
ブラウザ自動化不要。これらのシステムが要求する正確なCookieとヘッダーを返すシンプルなAPI呼び出し。
-
🚀
- 登録
- | 💬
- Discord
ScraplingはCloudflare Turnstileに対応。エンタープライズレベルの保護には、
+ Hyper Solutions
+ がAkamai、DataDome、Kasada、Incapsula向けの有効なantibotトークンを生成するAPIエンドポイントを提供。シンプルなAPI呼び出しで、ブラウザ自動化不要。
-
-
プロキシは複雑で高価であるべきではないと考え、BirdProxiesを構築しました。
195以上のロケーションの高速レジデンシャル・ISPプロキシ、公正な価格設定、そして本物のサポート。
+ プロキシは複雑で高価であるべきではないと考え、
+ BirdProxies
+ を構築しました。
195以上のロケーションの高速レジデンシャル・ISPプロキシ、公正な価格設定、そして本物のサポート。
ランディングページでFlappyBirdゲームを試して無料データをゲット!
-
🚀
- 今すぐ試す
- | 💬
- Discord
-
+
-
-
Evomi:レジデンシャルプロキシが $0.49/GB から。完全に偽装された Chromium によるスクレイピングブラウザ、レジデンシャル IP、自動 CAPTCHA 解決、アンチボットバイパス。
+
+
+ Evomi
+ :レジデンシャルプロキシが $0.49/GB から。完全に偽装された Chromium によるスクレイピングブラウザ、レジデンシャル IP、自動 CAPTCHA 解決、アンチボットバイパス。
Scraper API で手間なく結果を取得。MCP と N8N の統合に対応。
-
+
🚀
- 今すぐ試す
+
+
+
+
+
+
+ TikHub.io は TikTok、X、YouTube、Instagram を含む 16 以上のプラットフォームで 900 以上の安定した API を提供し、4,000 万以上のデータセットを保有。
+
さらに 割引 AI モデルも提供 — Claude、GPT、GEMINI など最大 71% オフ。
+
+
+
+
+
+
+
+
+ Nsocks は開発者やスクレイパー向けの高速なレジデンシャルおよび ISP プロキシを提供。グローバル IP カバレッジ、高い匿名性、スマートなローテーション、自動化とデータ抽出のための信頼性の高いパフォーマンス。Xcrawl で大規模ウェブクローリングを簡素化。
+
+
+
@@ -133,15 +156,10 @@ MySpider().start()
-
+
+
+
+
+
+ ノートパソコンを閉じても、スクレイパーは動き続けます。
+ PetroSky VPS - ノンストップ自動化のために構築されたクラウドサーバー。WindowsとLinuxマシンを完全制御。月額€6.99から。
+
-
-
-
-
-
+
diff --git a/docs/README_KR.md b/docs/README_KR.md
new file mode 100644
index 0000000..82cd44e
--- /dev/null
+++ b/docs/README_KR.md
@@ -0,0 +1,506 @@
+
+
+
+
+
+
+
+
+ Effortless Web Scraping for the Modern Web
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+여기에 광고를 게재하고 싶으신가요? [여기](https://github.com/sponsors/D4Vinci/sponsorships?tier_id=586646)를 클릭하세요
+# 스폰서
+
+
+
+
+
+
+
+
+
+
+ Scrapling은 Cloudflare Turnstile을 처리합니다. 엔터프라이즈급 보호가 필요하다면,
+ Hyper Solutions
+ 가 Akamai, DataDome, Kasada, Incapsula용 유효한 안티봇 토큰을 생성하는 API 엔드포인트를 제공합니다. 간단한 API 호출만으로, 브라우저 자동화가 필요 없습니다.
+
+
+
+
+
+
+
+ 프록시는 복잡하거나 비쌀 이유가 없다는 생각으로
+ BirdProxies
+ 를 만들었습니다.
+
195개 이상 지역의 빠른 레지덴셜 및 ISP 프록시, 합리적인 가격, 실질적인 지원.
+ 랜딩 페이지에서 FlappyBird 게임을 플레이하고 무료 데이터를 받으세요!
+
+
+
+
+
+
+
+
+
+ Evomi
+ : 레지덴셜 프록시 GB당 $0.49부터. 완전히 위장된 Chromium 스크레이핑 브라우저, 레지덴셜 IP, 자동 CAPTCHA 해결, 안티봇 우회.
+ Scraper API로 번거로움 없이 결과를 얻으세요. MCP 및 N8N 통합 지원.
+
+
+
+
+
+
+
+
+
+ TikHub.io는 TikTok, X, YouTube, Instagram 등 16개 이상 플랫폼에서 900개 이상의 안정적인 API를 제공하며, 4,000만 이상의 데이터셋을 보유하고 있습니다.
+
할인된 AI 모델도 제공 — Claude, GPT, GEMINI 등 최대 71% 할인.
+
+
+
+
+
+
+
+
+ Nsocks는 개발자와 스크레이퍼를 위한 빠른 레지덴셜 및 ISP 프록시를 제공합니다. 글로벌 IP 커버리지, 높은 익명성, 스마트 로테이션, 자동화와 데이터 추출을 위한 안정적인 성능. Xcrawl로 대규모 웹 크롤링을 간소화하세요.
+
+
+
+
+
+
+
+
+
+ 노트북을 닫으세요. 스크래퍼는 계속 작동합니다.
+
+ PetroSky VPS - 논스톱 자동화를 위한 클라우드 서버. Windows 및 Linux 머신을 완벽하게 제어. 월 €6.99부터.
+
+
+
+
+
+
+
+
+
+여기에 광고를 게재하고 싶으신가요? [여기](https://github.com/sponsors/D4Vinci)를 클릭하고 원하는 티어를 선택하세요!
+
+---
+
+## 주요 기능
+
+### Spider — 본격적인 크롤링 프레임워크
+- 🕷️ **Scrapy 스타일 Spider API**: `start_urls`, 비동기 `parse` 콜백, `Request`/`Response` 객체로 Spider를 정의합니다.
+- ⚡ **동시 크롤링**: 설정 가능한 동시 요청 수 제한, 도메인별 스로틀링, 다운로드 딜레이를 지원합니다.
+- 🔄 **멀티 세션 지원**: HTTP 요청과 스텔스 헤드리스 브라우저를 하나의 인터페이스로 통합 — ID로 요청을 다른 세션에 라우팅합니다.
+- 💾 **일시정지 & 재개**: 체크포인트 기반의 크롤링 영속화. Ctrl+C로 정상 종료하고, 재시작하면 중단된 지점부터 이어갑니다.
+- 📡 **스트리밍 모드**: `async for item in spider.stream()`으로 스크레이핑된 아이템을 실시간 통계와 함께 스트리밍으로 수신 — UI, 파이프라인, 장시간 크롤링에 적합합니다.
+- 🛡️ **차단된 요청 감지**: 커스텀 로직을 통한 차단된 요청의 자동 감지 및 재시도를 지원합니다.
+- 📦 **내장 내보내기**: 훅이나 자체 파이프라인, 또는 내장 JSON/JSONL로 결과를 내보냅니다. 각각 `result.items.to_json()` / `result.items.to_jsonl()`을 사용합니다.
+
+### 세션을 지원하는 고급 웹사이트 가져오기
+- **HTTP 요청**: `Fetcher` 클래스로 빠르고 은밀한 HTTP 요청. 브라우저의 TLS fingerprint, 헤더를 모방하고, HTTP/3를 사용할 수 있습니다.
+- **동적 로딩**: Playwright의 Chromium과 Google Chrome을 지원하는 `DynamicFetcher` 클래스로 완전한 브라우저 자동화를 통해 동적 웹사이트를 가져옵니다.
+- **안티봇 우회**: `StealthyFetcher`와 fingerprint 위장을 통한 고급 스텔스 기능. 자동화로 모든 유형의 Cloudflare Turnstile/Interstitial을 손쉽게 우회합니다.
+- **세션 관리**: `FetcherSession`, `StealthySession`, `DynamicSession` 클래스로 요청 간 쿠키와 상태를 관리하는 영속적 세션을 지원합니다.
+- **프록시 로테이션**: 모든 세션 타입에 대응하는 순환 또는 커스텀 전략의 내장 `ProxyRotator`와 요청별 프록시 오버라이드를 제공합니다.
+- **도메인 차단**: 브라우저 기반 Fetcher에서 특정 도메인(및 하위 도메인)으로의 요청을 차단합니다.
+- **비동기 지원**: 모든 Fetcher와 전용 비동기 세션 클래스에서 완전한 비동기를 지원합니다.
+
+### 적응형 스크레이핑 & AI 통합
+- 🔄 **스마트 요소 추적**: 지능적인 유사도 알고리즘으로 웹사이트 변경 후에도 요소를 재배치합니다.
+- 🎯 **유연한 스마트 선택**: CSS selector, XPath selector, 필터 기반 검색, 텍스트 검색, 정규식 검색 등을 지원합니다.
+- 🔍 **유사 요소 찾기**: 발견된 요소와 유사한 요소를 자동으로 찾아냅니다.
+- 🤖 **AI와 함께 사용하는 MCP 서버**: AI 기반 Web Scraping과 데이터 추출을 위한 내장 MCP 서버. AI(Claude/Cursor 등)에 전달하기 전에 Scrapling을 활용해 대상 콘텐츠를 추출하는 강력한 커스텀 기능을 갖추고 있어, 작업 속도를 높이고 토큰 사용량을 최소화해 비용을 절감합니다. ([데모 영상](https://www.youtube.com/watch?v=qyFk3ZNwOxE))
+
+### 고성능 & 실전 검증된 아키텍처
+- 🚀 **초고속**: 대부분의 Python 스크레이핑 라이브러리를 능가하는 최적화된 성능.
+- 🔋 **메모리 효율**: 최적화된 데이터 구조와 지연 로딩으로 메모리 사용을 최소화합니다.
+- ⚡ **고속 JSON 직렬화**: 표준 라이브러리보다 10배 빠릅니다.
+- 🏗️ **실전 검증**: Scrapling은 92%의 테스트 커버리지와 완전한 타입 힌트 커버리지를 갖추고 있을 뿐 아니라, 지난 1년간 수백 명의 Web Scraper가 매일 사용해 왔습니다.
+
+### 개발자/Web Scraper 친화적 경험
+- 🎯 **인터랙티브 Web Scraping Shell**: Scrapling 통합, 단축키, curl 요청을 Scrapling 요청으로 변환하거나 브라우저에서 요청 결과를 확인하는 등의 도구를 갖춘 선택적 내장 IPython Shell로, Web Scraping 스크립트 개발을 가속합니다.
+- 🚀 **터미널에서 바로 사용**: 코드 한 줄 없이 Scrapling으로 URL을 스크레이핑할 수 있습니다!
+- 🛠️ **풍부한 내비게이션 API**: 부모, 형제, 자식 탐색 메서드를 통한 고급 DOM 순회를 지원합니다.
+- 🧬 **향상된 텍스트 처리**: 내장 정규식, 클리닝 메서드, 최적화된 문자열 연산을 제공합니다.
+- 📝 **자동 셀렉터 생성**: 모든 요소에 대해 견고한 CSS/XPath selector를 생성합니다.
+- 🔌 **익숙한 API**: Scrapy/Parsel에서 사용하는 것과 동일한 의사 요소(pseudo-element)를 가진 Scrapy/BeautifulSoup 스타일의 API.
+- 📘 **완전한 타입 커버리지**: 뛰어난 IDE 지원과 코드 자동완성을 위한 완전한 타입 힌트. 코드베이스 전체가 변경될 때마다 **PyRight**와 **MyPy**로 자동 검사됩니다.
+- 🔋 **바로 사용 가능한 Docker 이미지**: 매 릴리스마다 모든 브라우저를 포함한 Docker 이미지가 자동으로 빌드 및 푸시됩니다.
+
+## 시작하기
+
+깊이 들어가지 않고, Scrapling이 할 수 있는 것들을 간단히 살펴보겠습니다.
+
+### 기본 사용법
+세션을 지원하는 HTTP 요청
+```python
+from scrapling.fetchers import Fetcher, FetcherSession
+
+with FetcherSession(impersonate='chrome') as session: # Chrome의 최신 TLS fingerprint 사용
+ page = session.get('https://quotes.toscrape.com/', stealthy_headers=True)
+ quotes = page.css('.quote .text::text').getall()
+
+# 또는 일회성 요청 사용
+page = Fetcher.get('https://quotes.toscrape.com/')
+quotes = page.css('.quote .text::text').getall()
+```
+고급 스텔스 모드
+```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')
+data = page.css('#padded_content a').getall()
+```
+완전한 브라우저 자동화
+```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() # 원하시면 XPath selector도 사용 가능
+
+# 또는 일회성 요청 스타일 — 이 요청을 위해 브라우저를 열고, 완료 후 닫습니다
+page = DynamicFetcher.fetch('https://quotes.toscrape.com/')
+data = page.css('.quote .text::text').getall()
+```
+
+### 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(),
+ }
+
+ next_page = response.css('.next a')
+ if next_page:
+ yield response.follow(next_page[0].attrib['href'])
+
+result = QuotesSpider().start()
+print(f"{len(result.items)}개의 인용구를 스크레이핑했습니다")
+result.items.to_json("quotes.json")
+```
+하나의 Spider에서 여러 세션 타입 사용:
+```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) # 명시적 콜백
+```
+체크포인트를 사용해 장시간 크롤링을 일시정지 & 재개:
+```python
+QuotesSpider(crawldir="./crawl_data").start()
+```
+Ctrl+C를 누르면 정상적으로 일시정지되고, 진행 상황이 자동 저장됩니다. 이후 Spider를 다시 시작할 때 동일한 `crawldir`을 전달하면 중단된 지점부터 재개합니다.
+
+### 고급 파싱 & 내비게이션
+```python
+from scrapling.fetchers import Fetcher
+
+# 풍부한 요소 선택과 내비게이션
+page = Fetcher.get('https://quotes.toscrape.com/')
+
+# 여러 선택 메서드로 인용구 가져오기
+quotes = page.css('.quote') # CSS selector
+quotes = page.xpath('//div[@class="quote"]') # XPath
+quotes = page.find_all('div', {'class': 'quote'}) # BeautifulSoup 스타일
+# 아래와 동일
+quotes = page.find_all('div', class_='quote')
+quotes = page.find_all(['div'], class_='quote')
+quotes = page.find_all(class_='quote') # 등등...
+# 텍스트 내용으로 요소 찾기
+quotes = page.find_by_text('quote', tag='div')
+
+# 고급 내비게이션
+quote_text = page.css('.quote')[0].css('.text::text').get()
+quote_text = page.css('.quote').css('.text::text').getall() # 체이닝 셀렉터
+first_quote = page.css('.quote')[0]
+author = first_quote.next_sibling.css('.author::text')
+parent_container = first_quote.parent
+
+# 요소 관계와 유사도
+similar_elements = first_quote.find_similar()
+below_elements = first_quote.below_elements()
+```
+웹사이트를 가져오지 않고 파서를 바로 사용할 수도 있습니다:
+```python
+from scrapling.parser import Selector
+
+page = Selector("...")
+```
+사용법은 완전히 동일합니다!
+
+### 비동기 세션 관리 예시
+```python
+import asyncio
+from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession
+
+async with FetcherSession(http3=True) as session: # `FetcherSession`은 컨텍스트 인식이 가능하며 동기/비동기 패턴 모두에서 작동
+ page1 = session.get('https://quotes.toscrape.com/')
+ page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135')
+
+# 비동기 세션 사용
+async with AsyncStealthySession(max_pages=2) as session:
+ tasks = []
+ urls = ['https://example.com/page1', 'https://example.com/page2']
+
+ for url in urls:
+ task = session.fetch(url)
+ tasks.append(task)
+
+ print(session.get_pool_stats()) # 선택 사항 - 브라우저 탭 풀 상태 (사용 중/유휴/에러)
+ results = await asyncio.gather(*tasks)
+ print(session.get_pool_stats())
+```
+
+## CLI & 인터랙티브 Shell
+
+Scrapling에는 강력한 커맨드라인 인터페이스가 포함되어 있습니다:
+
+[](https://asciinema.org/a/736339)
+
+인터랙티브 Web Scraping Shell 실행
+```bash
+scrapling shell
+```
+프로그래밍 없이 페이지를 파일로 바로 추출합니다 (기본적으로 `body` 태그 내부의 콘텐츠를 추출). 출력 파일이 `.txt`로 끝나면 대상의 텍스트 콘텐츠가 추출됩니다. `.md`로 끝나면 HTML 콘텐츠의 Markdown 표현이 됩니다. `.html`로 끝나면 HTML 콘텐츠 자체가 됩니다.
+```bash
+scrapling extract get 'https://example.com' content.md
+scrapling extract get 'https://example.com' content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome' # 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 Scraping Shell 등 더 많은 기능이 있지만, 이 페이지는 간결하게 유지하겠습니다. 전체 문서는 [여기](https://scrapling.readthedocs.io/en/latest/)에서 확인하세요.
+
+## 성능 벤치마크
+
+Scrapling은 강력할 뿐만 아니라 초고속입니다. 아래 벤치마크는 Scrapling의 파서를 다른 인기 라이브러리의 최신 버전과 비교한 것입니다.
+
+### 텍스트 추출 속도 테스트 (5000개 중첩 요소)
+
+| # | Library | Time (ms) | vs Scrapling |
+|---|:-----------------:|:---------:|:------------:|
+| 1 | Scrapling | 2.02 | 1.0x |
+| 2 | Parsel/Scrapy | 2.04 | 1.01 |
+| 3 | Raw Lxml | 2.54 | 1.257 |
+| 4 | PyQuery | 24.17 | ~12x |
+| 5 | Selectolax | 82.63 | ~41x |
+| 6 | MechanicalSoup | 1549.71 | ~767.1x |
+| 7 | BS4 with Lxml | 1584.31 | ~784.3x |
+| 8 | BS4 with html5lib | 3391.91 | ~1679.1x |
+
+
+### 요소 유사도 & 텍스트 검색 성능
+
+Scrapling의 적응형 요소 찾기 기능은 대안들을 크게 앞섭니다:
+
+| Library | Time (ms) | vs Scrapling |
+|-------------|:---------:|:------------:|
+| Scrapling | 2.39 | 1.0x |
+| AutoScraper | 12.45 | 5.209x |
+
+
+> 모든 벤치마크는 100회 이상 실행의 평균입니다. 측정 방법은 [benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py)를 참조하세요.
+
+## 설치
+
+Scrapling은 Python 3.10 이상이 필요합니다:
+
+```bash
+pip install scrapling
+```
+
+이 설치에는 파서 엔진과 의존성만 포함되며, Fetcher나 커맨드라인 의존성은 포함되지 않습니다.
+
+### 선택적 의존성
+
+1. 아래의 추가 기능, Fetcher, 또는 관련 클래스를 사용하려면 Fetcher 의존성과 브라우저 의존성을 다음과 같이 설치해야 합니다:
+ ```bash
+ pip install "scrapling[fetchers]"
+
+ scrapling install # 일반 설치
+ scrapling install --force # 강제 재설치
+ ```
+
+ 이렇게 하면 모든 브라우저와 시스템 의존성, fingerprint 조작 의존성이 다운로드됩니다.
+
+ 또는 명령어 대신 코드에서 설치할 수도 있습니다:
+ ```python
+ from scrapling.cli import install
+
+ install([], standalone_mode=False) # 일반 설치
+ install(["--force"], standalone_mode=False) # 강제 재설치
+ ```
+
+2. 추가 기능:
+ - MCP 서버 기능 설치:
+ ```bash
+ pip install "scrapling[ai]"
+ ```
+ - Shell 기능 (Web Scraping Shell 및 `extract` 명령어) 설치:
+ ```bash
+ pip install "scrapling[shell]"
+ ```
+ - 모든 기능 설치:
+ ```bash
+ pip install "scrapling[all]"
+ ```
+ 위 추가 기능을 설치한 후에도 (아직 하지 않았다면) `scrapling install`로 브라우저 의존성을 설치해야 합니다.
+
+### Docker
+DockerHub에서 모든 추가 기능과 브라우저가 포함된 Docker 이미지를 설치할 수도 있습니다:
+```bash
+docker pull pyd4vinci/scrapling
+```
+또는 GitHub 레지스트리에서 다운로드:
+```bash
+docker pull ghcr.io/d4vinci/scrapling:latest
+```
+이 이미지는 GitHub Actions와 레포지토리의 main 브랜치를 사용하여 자동으로 빌드 및 푸시됩니다.
+
+## 기여하기
+
+기여를 환영합니다! 시작하기 전에 [기여 가이드라인](https://github.com/D4Vinci/Scrapling/blob/main/CONTRIBUTING.md)을 읽어주세요.
+
+## 면책 조항
+
+> [!CAUTION]
+> 이 라이브러리는 교육 및 연구 목적으로만 제공됩니다. 이 라이브러리를 사용함으로써, 국내외 데이터 스크레이핑 및 개인정보 보호 관련 법률을 준수하는 데 동의한 것으로 간주됩니다. 저자와 기여자는 이 소프트웨어의 오용에 대해 책임지지 않습니다. 항상 웹사이트의 이용약관과 robots.txt 파일을 존중하세요.
+
+## 🎓 인용
+연구 목적으로 이 라이브러리를 사용하셨다면, 아래 참고 문헌으로 인용해 주세요:
+```text
+ @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!}
+ }
+```
+
+## 라이선스
+
+이 프로젝트는 BSD-3-Clause 라이선스 하에 배포됩니다.
+
+## 감사의 말
+
+이 프로젝트에는 다음에서 차용한 코드가 포함되어 있습니다:
+- Parsel (BSD 라이선스) — [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py) 서브모듈에 사용
+
+---
+
diff --git a/docs/README_RU.md b/docs/README_RU.md
index a07b337..8532627 100644
--- a/docs/README_RU.md
+++ b/docs/README_RU.md
@@ -16,8 +16,11 @@
-
-
+
+
+
+
+
@@ -84,47 +87,70 @@ MySpider().start()
-
-
Fetcher'ы Scrapling справляются с Cloudflare Turnstile, но для защиты корпоративного уровня Hyper Solutions предоставляет API-эндпоинты, генерирующие валидные antibot-токены для:
Akamai • DataDome • Kasada • Incapsula
-
Без автоматизации браузера. Простые API-вызовы, возвращающие именно те cookie и заголовки, которые требуют эти системы.
-
🚀
- Подписаться
- | 💬
- Discord
-
+ Scrapling справляется с Cloudflare Turnstile. Для защиты корпоративного уровня
+
+ Hyper Solutions
+ предоставляет API-эндпоинты, генерирующие валидные antibot-токены для Akamai, DataDome, Kasada и Incapsula . Простые API-вызовы, без автоматизации браузера.
-
-
Мы создали BirdProxies, потому что прокси не должны быть сложными или дорогими.
Быстрые резидентные и ISP прокси в 195+ локациях, честные цены и настоящая поддержка.
+ Мы создали
+
+ BirdProxies
+ , потому что прокси не должны быть сложными или дорогими.
Быстрые резидентные и ISP прокси в 195+ локациях, честные цены и настоящая поддержка.
Попробуйте нашу игру FlappyBird на лендинге и получите бесплатные данные!
-
🚀
- Попробовать
- | 💬
- Discord
-
+
-
-
Evomi: резидентные прокси от $0.49/ГБ. Браузер для скрапинга с полностью подменённым Chromium, резидентными IP, автоматическим решением CAPTCHA и обходом анти-бот систем.
+
+
+ Evomi
+ : резидентные прокси от $0.49/ГБ. Браузер для скрапинга с полностью подменённым Chromium, резидентными IP, автоматическим решением CAPTCHA и обходом анти-бот систем.
Scraper API для получения результатов без лишних сложностей. Доступны интеграции с MCP и N8N.
-
+
🚀
- Попробовать
+
+
+
+
+
+
+ TikHub.io предоставляет более 900 стабильных API на 16+ платформах, включая TikTok, X, YouTube и Instagram, с более чем 40 млн наборов данных.
+
Также предлагает AI-модели со скидкой — Claude, GPT, GEMINI и другие со скидкой до 71%.
+
+
+
+
+
+
+
+
+ Nsocks предоставляет быстрые резидентные и ISP прокси для разработчиков и скраперов. Глобальное покрытие IP, высокая анонимность, умная ротация и надёжная производительность для автоматизации и извлечения данных. Используйте Xcrawl для упрощения масштабного веб-краулинга.
+
+
+
@@ -133,15 +159,10 @@ MySpider().start()
-
+
+
+
+
+
+ Закройте ноутбук. Ваши скраперы продолжают работать.
+ PetroSky VPS - облачные серверы для непрерывной автоматизации. Машины на Windows и Linux с полным контролем. От €6,99/мес.
+
-
-
-
-
-
+
diff --git a/docs/donate.md b/docs/donate.md
index af616d4..9b8db24 100644
--- a/docs/donate.md
+++ b/docs/donate.md
@@ -23,7 +23,7 @@ Perks:
### 3. [The Platinum tier](https://github.com/sponsors/D4Vinci/sponsorships?tier_id=586646) ($300/month)
Perks:
-1. Your logo will have a special placement at [the very top of Scrapling's project page](https://github.com/D4Vinci/Scrapling?tab=readme-ov-file#platinum-sponsors) with a 35-word paragraph or less.
+1. Your logo will have a special placement at [the very top of Scrapling's project page](https://github.com/D4Vinci/Scrapling?tab=readme-ov-file#platinum-sponsors) with a 30-word paragraph or less.
2. The same logo will be featured at [the PyPI page](https://pypi.org/project/scrapling/)/[the Docker page](https://hub.docker.com/r/pyd4vinci/scrapling), the same way it was placed on the project's page.
3. A special placement for your logo as a top sponsor on [Scrapling's website](https://scrapling.readthedocs.io/en/latest/) main page.
4. A partner role at our Discord server and an announcement on the Twitter page and the Discord server.
diff --git a/docs/fetching/dynamic.md b/docs/fetching/dynamic.md
index 31574a6..1d33a59 100644
--- a/docs/fetching/dynamic.md
+++ b/docs/fetching/dynamic.md
@@ -76,8 +76,8 @@ Scrapling provides many options with this fetcher and its session classes. To ma
| wait_selector | Wait for a specific css selector to be in a specific state. | ✔️ |
| init_script | An absolute path to a JavaScript file to be executed on page creation for all pages in this session. | ✔️ |
| wait_selector_state | Scrapling will wait for the given state to be fulfilled for the selector given with `wait_selector`. _Default state is `attached`._ | ✔️ |
-| google_search | Enabled by default, Scrapling will set the referer header as if this request came from a Google search of this website's domain name. | ✔️ |
-| extra_headers | A dictionary of extra headers to add to the request. _The referer set by the `google_search` argument takes priority over the referer set here if used together._ | ✔️ |
+| google_search | Enabled by default, Scrapling will set a Google referer header. | ✔️ |
+| extra_headers | A dictionary of extra headers to add to the request. _The referer set by `google_search` takes priority over the referer set here if used together._ | ✔️ |
| proxy | The proxy to be used with requests. It can be a string or a dictionary with only the keys 'server', 'username', and 'password'. | ✔️ |
| real_chrome | If you have a Chrome browser installed on your device, enable this, and the Fetcher will launch and use an instance of your browser. | ✔️ |
| locale | Specify user locale, for example, `en-GB`, `de-DE`, etc. Locale will affect `navigator.language` value, `Accept-Language` request header value, as well as number and date formatting rules. Defaults to the system default locale. | ✔️ |
@@ -97,7 +97,7 @@ In session classes, all these arguments can be set globally for the session. Sti
!!! note "Notes:"
1. The `disable_resources` option made requests ~25% faster in my tests for some websites and can help save your proxy usage, but be careful with it, as it can cause some websites to never finish loading.
- 2. The `google_search` argument is enabled by default for all requests, making the request appear to come from a Google search page. So, a request for `https://example.com` will set the referer to `https://www.google.com/search?q=example`. Also, if used together, it takes priority over the referer set by the `extra_headers` argument.
+ 2. The `google_search` argument is enabled by default for all requests, setting the referer to `https://www.google.com/`. If used together with `extra_headers`, it takes priority over the referer set there.
3. Since version 0.3.13, the `stealth` option has been removed here in favor of the `StealthyFetcher` class, and the `hide_canvas` option has been moved to it. The `disable_webgl` argument has been moved to the `StealthyFetcher` class and renamed as `allow_webgl`.
4. If you didn't set a user agent and enabled headless mode, the fetcher will generate a real user agent for the same browser version and use it. If you didn't set a user agent and didn't enable headless mode, the fetcher will use the browser's default user agent, which is the same as in standard browsers in the latest versions.
diff --git a/docs/fetching/static.md b/docs/fetching/static.md
index 0071785..587ebd1 100644
--- a/docs/fetching/static.md
+++ b/docs/fetching/static.md
@@ -20,7 +20,7 @@ Check out how to configure the parsing options [here](choosing.md#parser-configu
All methods for making requests here share some arguments, so let's discuss them first.
- **url**: The targeted URL
-- **stealthy_headers**: If enabled (default), it creates and adds real browser headers. It also sets the referer header as if this request came from a Google search of the URL's domain.
+- **stealthy_headers**: If enabled (default), it creates and adds real browser headers. It also sets a Google referer header.
- **follow_redirects**: As the name implies, tell the fetcher to follow redirections. **Enabled by default**
- **timeout**: The number of seconds to wait for each request to be finished. **Defaults to 30 seconds**.
- **retries**: The number of retries that the fetcher will do for failed requests. **Defaults to three retries**.
diff --git a/docs/fetching/stealthy.md b/docs/fetching/stealthy.md
index fcbc8ea..4fd888e 100644
--- a/docs/fetching/stealthy.md
+++ b/docs/fetching/stealthy.md
@@ -32,8 +32,7 @@ The `StealthyFetcher` class is a stealthy version of the [DynamicFetcher](dynami
3. It isolates JS execution, removes many Playwright fingerprints, and stops detection through some of the known behaviors that bots do.
4. It generates canvas noise to prevent fingerprinting through canvas.
5. It automatically patches known methods to detect running in headless mode and provides an option to defeat timezone mismatch attacks.
-6. It makes requests look as if they came from Google's search page of the requested website.
-7. and other anti-protection options...
+6. and other anti-protection options...
## Full list of arguments
Scrapling provides many options with this fetcher and its session classes. Before jumping to the [examples](#examples), here's the full list of arguments
@@ -54,8 +53,8 @@ Scrapling provides many options with this fetcher and its session classes. Befor
| wait_selector | Wait for a specific css selector to be in a specific state. | ✔️ |
| init_script | An absolute path to a JavaScript file to be executed on page creation for all pages in this session. | ✔️ |
| wait_selector_state | Scrapling will wait for the given state to be fulfilled for the selector given with `wait_selector`. _Default state is `attached`._ | ✔️ |
-| google_search | Enabled by default, Scrapling will set the referer header as if this request came from a Google search of this website's domain name. | ✔️ |
-| extra_headers | A dictionary of extra headers to add to the request. _The referer set by the `google_search` argument takes priority over the referer set here if used together._ | ✔️ |
+| google_search | Enabled by default, Scrapling will set a Google referer header. | ✔️ |
+| extra_headers | A dictionary of extra headers to add to the request. _The referer set by `google_search` takes priority over the referer set here if used together._ | ✔️ |
| proxy | The proxy to be used with requests. It can be a string or a dictionary with only the keys 'server', 'username', and 'password'. | ✔️ |
| real_chrome | If you have a Chrome browser installed on your device, enable this, and the Fetcher will launch and use an instance of your browser. | ✔️ |
| locale | Specify user locale, for example, `en-GB`, `de-DE`, etc. Locale will affect `navigator.language` value, `Accept-Language` request header value, as well as number and date formatting rules. Defaults to the system default locale. | ✔️ |
@@ -80,7 +79,7 @@ In session classes, all these arguments can be set globally for the session. Sti
1. It's basically the same arguments as [DynamicFetcher](dynamic.md#introduction) class, but with these additional arguments: `solve_cloudflare`, `block_webrtc`, `hide_canvas`, and `allow_webgl`.
2. The `disable_resources` option made requests ~25% faster in my tests for some websites and can help save your proxy usage, but be careful with it, as it can cause some websites to never finish loading.
- 3. The `google_search` argument is enabled by default for all requests, making the request appear to come from a Google search page. So, a request for `https://example.com` will set the referer to `https://www.google.com/search?q=example`. Also, if used together, it takes priority over the referer set by the `extra_headers` argument.
+ 3. The `google_search` argument is enabled by default for all requests, setting the referer to `https://www.google.com/`. If used together with `extra_headers`, it takes priority over the referer set there.
4. If you didn't set a user agent and enabled headless mode, the fetcher will generate a real user agent for the same browser version and use it. If you didn't set a user agent and didn't enable headless mode, the fetcher will use the browser's default user agent, which is the same as in standard browsers in the latest versions.
## Examples
diff --git a/docs/index.md b/docs/index.md
index ab9e2ba..8bd5ed2 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -51,8 +51,9 @@ MySpider().start()
+ 

-
+