247153575d
Tests / tests (map[TOXENV:py310], macos-latest, 3.10) (push) Has been cancelled
Tests / tests (map[TOXENV:py311], macos-latest, 3.11) (push) Has been cancelled
Tests / tests (map[TOXENV:py312], macos-latest, 3.12) (push) Has been cancelled
Tests / tests (map[TOXENV:py313], macos-latest, 3.13) (push) Has been cancelled
538 lines
31 KiB
Markdown
538 lines
31 KiB
Markdown
<!-- mcp-name: io.github.D4Vinci/Scrapling -->
|
|
|
|
<h1 align="center">
|
|
<a href="https://scrapling.readthedocs.io">
|
|
<picture>
|
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/docs/assets/cover_dark.svg?sanitize=true">
|
|
<img alt="Scrapling Poster" src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/docs/assets/cover_light.svg?sanitize=true">
|
|
</picture>
|
|
</a>
|
|
<br>
|
|
<small>Effortless Web Scraping for the Modern Web</small>
|
|
</h1>
|
|
|
|
<p align="center">
|
|
<a href="https://github.com/D4Vinci/Scrapling/actions/workflows/tests.yml" alt="Tests">
|
|
<img alt="Tests" src="https://github.com/D4Vinci/Scrapling/actions/workflows/tests.yml/badge.svg"></a>
|
|
<a href="https://badge.fury.io/py/Scrapling" alt="PyPI version">
|
|
<img alt="PyPI version" src="https://badge.fury.io/py/Scrapling.svg"></a>
|
|
<a href="https://clickpy.clickhouse.com/dashboard/scrapling" rel="nofollow"><img src="https://img.shields.io/pypi/dm/scrapling" alt="PyPI package downloads"></a>
|
|
<a href="https://github.com/D4Vinci/Scrapling/tree/main/agent-skill" alt="AI Agent Skill directory">
|
|
<img alt="Static Badge" src="https://img.shields.io/badge/Skill-black?style=flat&label=Agent&link=https%3A%2F%2Fgithub.com%2FD4Vinci%2FScrapling%2Ftree%2Fmain%2Fagent-skill"></a>
|
|
<a href="https://clawhub.ai/D4Vinci/scrapling-official" alt="OpenClaw Skill">
|
|
<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>
|
|
<br/>
|
|
<a href="https://discord.gg/EMgGbDceNQ" alt="Discord" target="_blank">
|
|
<img alt="Discord" src="https://img.shields.io/discord/1360786381042880532?style=social&logo=discord&link=https%3A%2F%2Fdiscord.gg%2FEMgGbDceNQ">
|
|
</a>
|
|
<a href="https://x.com/Scrapling_dev" alt="X (formerly Twitter)">
|
|
<img alt="X (formerly Twitter) Follow" src="https://img.shields.io/twitter/follow/Scrapling_dev?style=social&logo=x&link=https%3A%2F%2Fx.com%2FScrapling_dev">
|
|
</a>
|
|
<br/>
|
|
<a href="https://pypi.org/project/scrapling/" alt="Supported Python versions">
|
|
<img alt="Supported Python versions" src="https://img.shields.io/pypi/pyversions/scrapling.svg"></a>
|
|
</p>
|
|
|
|
<p align="center">
|
|
<a href="https://scrapling.readthedocs.io/en/latest/parsing/selection.html"><strong>Métodos de selección</strong></a>
|
|
·
|
|
<a href="https://scrapling.readthedocs.io/en/latest/fetching/choosing.html"><strong>Elegir un fetcher</strong></a>
|
|
·
|
|
<a href="https://scrapling.readthedocs.io/en/latest/spiders/architecture.html"><strong>Spiders</strong></a>
|
|
·
|
|
<a href="https://scrapling.readthedocs.io/en/latest/spiders/proxy-blocking.html"><strong>Rotación de proxy</strong></a>
|
|
·
|
|
<a href="https://scrapling.readthedocs.io/en/latest/cli/overview.html"><strong>CLI</strong></a>
|
|
·
|
|
<a href="https://scrapling.readthedocs.io/en/latest/ai/mcp-server.html"><strong>Modo MCP</strong></a>
|
|
</p>
|
|
|
|
Scrapling es un framework de Web Scraping adaptativo que se encarga de todo, desde una sola solicitud hasta un rastreo a gran escala.
|
|
|
|
Su parser aprende de los cambios de los sitios web y relocaliza automáticamente tus elementos cuando las páginas se actualizan. Sus fetchers evaden sistemas anti-bot como Cloudflare Turnstile de forma nativa. Y su framework Spider te permite escalar a rastreos concurrentes con múltiples sesiones, con Pause & Resume y rotación automática de Proxy, todo en unas pocas líneas de Python. Una biblioteca, cero compromisos.
|
|
|
|
Rastreos ultrarrápidos con estadísticas en tiempo real y Streaming. Construido por Web Scrapers para Web Scrapers y usuarios regulares, hay algo para todos.
|
|
|
|
```python
|
|
from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher
|
|
StealthyFetcher.adaptive = True
|
|
p = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # ¡Obtén el sitio web bajo el radar!
|
|
products = p.css('.product', auto_save=True) # ¡Extrae datos que sobreviven a cambios de diseño del sitio web!
|
|
products = p.css('.product', adaptive=True) # Más tarde, si la estructura del sitio web cambia, ¡pasa `adaptive=True` para encontrarlos!
|
|
```
|
|
O escala a rastreos completos
|
|
```python
|
|
from scrapling.spiders import Spider, Response
|
|
|
|
class MySpider(Spider):
|
|
name = "demo"
|
|
start_urls = ["https://example.com/"]
|
|
|
|
async def parse(self, response: Response):
|
|
for item in response.css('.product'):
|
|
yield {"title": item.css('h2::text').get()}
|
|
|
|
MySpider().start()
|
|
```
|
|
|
|
<p align="center">
|
|
<a href="https://dataimpulse.com/?utm_source=scrapling&utm_medium=banner&utm_campaign=scrapling" target="_blank" style="display:flex; justify-content:center; padding:4px 0;">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/DataImpulse.png" alt="At DataImpulse, we specialize in developing custom proxy services for your business. Make requests from anywhere, collect data, and enjoy fast connections with our premium proxies." style="max-height:60px;">
|
|
</a>
|
|
</p>
|
|
|
|
# Patrocinadores Platino
|
|
<table>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://proxidize.com/?utm_source=github&utm_medium=sponsorship&utm_campaign=scrapling&utm_content=d4vinci" target="_blank" title="Clean Proxies with No Nonsense.">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/proxidize.png">
|
|
</a>
|
|
</td>
|
|
<td> <a href="https://proxidize.com/?utm_source=github&utm_medium=sponsorship&utm_campaign=scrapling&utm_content=d4vinci" target="_blank"><b>Proxidize</b></a> proporciona proxies móviles y residenciales para scraping, automatización de navegadores, monitoreo de SEO, agentes de IA y recopilación de datos. <i>Usa el código <b>scrapling20</b> para obtener un 20% de descuento</i>.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://coldproxy.com/" target="_blank" title="Residential, IPv6 & Datacenter Proxies for Web Scraping">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/coldproxy.png">
|
|
</a>
|
|
</td>
|
|
<td> <a href="https://coldproxy.com/" target="_blank"><b>ColdProxy</b></a> proporciona proxies residenciales y de centros de datos para web scraping estable, recopilación de datos públicos y pruebas con segmentación geográfica en más de 195 países.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://hypersolutions.co/?utm_source=github&utm_medium=readme&utm_campaign=scrapling" target="_blank" title="Bot Protection Bypass API for Akamai, DataDome, Incapsula & Kasada">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/HyperSolutions.png">
|
|
</a>
|
|
</td>
|
|
<td> Scrapling maneja Cloudflare Turnstile. Para protección de nivel empresarial, <a href="https://hypersolutions.co?utm_source=github&utm_medium=readme&utm_campaign=scrapling">
|
|
<b>Hyper Solutions</b>
|
|
</a> proporciona endpoints API que generan tokens antibot válidos para <b>Akamai</b>, <b>DataDome</b>, <b>Kasada</b> e <b>Incapsula</b>. Simples llamadas API, sin automatización de navegador. </td>
|
|
</tr>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://evomi.com?utm_source=github&utm_medium=banner&utm_campaign=d4vinci-scrapling" target="_blank" title="Evomi is your Swiss Quality Proxy Provider, starting at $0.49/GB">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/evomi.png">
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<a href="https://evomi.com?utm_source=github&utm_medium=banner&utm_campaign=d4vinci-scrapling">
|
|
<b>Evomi</b>
|
|
</a>: 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. </br>
|
|
<b>API Scraper para resultados sin complicaciones. Integraciones MCP y N8N disponibles.</b>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://tikhub.io/?utm_source=github.com/D4Vinci/Scrapling&utm_medium=marketing_social&utm_campaign=retargeting&utm_content=carousel_ad" target="_blank" title="Unlock the Power of Social Media Data & AI">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/TikHub.jpg">
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<a href="https://tikhub.io/?utm_source=github.com/D4Vinci/Scrapling&utm_medium=marketing_social&utm_campaign=retargeting&utm_content=carousel_ad" target="_blank">TikHub.io</a> 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. <br /> También ofrece <a href="https://ai.tikhub.io/?ref=KarimShoair" target="_blank">modelos de IA con descuento</a> - Claude, GPT, GEMINI y más con hasta un 71% de descuento.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://petrosky.io/d4vinci" target="_blank" title="PetroSky delivers cutting-edge VPS hosting.">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/petrosky.png">
|
|
</a>
|
|
</td>
|
|
<td>
|
|
Cierra tu portátil. Tus scrapers siguen funcionando. <br />
|
|
<a href="https://petrosky.io/d4vinci" target="_blank">PetroSky VPS</a> - servidores en la nube diseñados para automatización ininterrumpida. Máquinas Windows y Linux con control total. Desde €6,99/mes.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://substack.thewebscraping.club/p/scrapling-hands-on-guide?utm_source=github&utm_medium=repo&utm_campaign=scrapling" target="_blank" title="The #1 newsletter dedicated to Web Scraping">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/TWSC.png">
|
|
</a>
|
|
</td>
|
|
<td>
|
|
Lee una reseña completa de <a href="https://substack.thewebscraping.club/p/scrapling-hands-on-guide?utm_source=github&utm_medium=repo&utm_campaign=scrapling" target="_blank">Scrapling en The Web Scraping Club</a> (nov. 2025), el boletín número uno dedicado al Web Scraping.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://www.swiftproxy.net/?ref=D4Vinci" target="_blank" title="Scalable Solutions for Web Data Access">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/SwiftProxy.png">
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<a href="https://www.swiftproxy.net/?ref=D4Vinci" target="_blank">Swiftproxy</a> ofrece proxies residenciales escalables con más de 80 millones de IPs en más de 195 países, brindando conexiones rápidas y fiables, rotación automática y un sólido rendimiento anti-bloqueo. Prueba gratuita disponible.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="200">
|
|
<a href="https://go.nodemaven.com/scraplingjune" target="_blank" title="Proxies with the Highest IP Scores">
|
|
<img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/NodeMaven.svg" width="240" height="100">
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<a href="https://go.nodemaven.com/scraplingjune" target="_blank">NodeMaven</a> - proveedor de proxies confiable con la mayor calidad de IP del mercado. Usa el código promocional SCRAPLING35 para obtener un 35% de descuento en proxies.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<i><sub>¿Quieres mostrar tu anuncio aquí? Haz clic [aquí](https://github.com/sponsors/D4Vinci/sponsorships?tier_id=586646)</sub></i>
|
|
# Patrocinadores
|
|
|
|
<!-- sponsors -->
|
|
|
|
<a href="https://serpapi.com/?utm_source=scrapling" target="_blank" title="Scrape Google and other search engines with SerpApi"><img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/SerpApi.png"></a>
|
|
<a href="https://visit.decodo.com/Dy6W0b" target="_blank" title="Try the Most Efficient Residential Proxies for Free"><img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/decodo.png"></a>
|
|
<a href="https://hasdata.com/?utm_source=github&utm_medium=banner&utm_campaign=D4Vinci" target="_blank" title="The web scraping service that actually beats anti-bot systems!"><img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/hasdata.png"></a>
|
|
<a href="https://proxyempire.io/?ref=scrapling&utm_source=scrapling" target="_blank" title="Collect The Data Your Project Needs with the Best Residential Proxies"><img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/ProxyEmpire.png"></a>
|
|
<a href="https://www.webshare.io/?referral_code=48r2m2cd5uz1" target="_blank" title="The Most Reliable Proxy with Unparalleled Performance"><img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/webshare.png"></a>
|
|
<a href="https://proxiware.com/?ref=scrapling" target="_blank" title="Collect Any Data. At Any Scale."><img src="https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/proxiware.png"></a>
|
|
|
|
|
|
<!-- /sponsors -->
|
|
|
|
<i><sub>¿Quieres mostrar tu anuncio aquí? ¡Haz clic [aquí](https://github.com/sponsors/D4Vinci) y elige el nivel que te convenga!</sub></i>
|
|
|
|
---
|
|
|
|
## Características Principales
|
|
|
|
### Spiders - Un Framework Completo de Rastreo
|
|
- 🕷️ **API de Spider al estilo Scrapy**: Define spiders con `start_urls`, callbacks async `parse`, y objetos `Request`/`Response`.
|
|
- ⚡ **Rastreo Concurrente**: Límites de concurrencia configurables, limitación por dominio y retrasos de descarga.
|
|
- 🔄 **Soporte Multi-Session**: Interfaz unificada para solicitudes HTTP y navegadores headless sigilosos en un solo Spider - enruta solicitudes a diferentes sesiones por ID.
|
|
- 💾 **Pause & Resume**: Persistencia de rastreo basada en Checkpoint. Presiona Ctrl+C para un cierre ordenado; reinicia para continuar desde donde lo dejaste.
|
|
- 📡 **Modo Streaming**: Transmite elementos extraídos a medida que llegan con `async for item in spider.stream()` con estadísticas en tiempo real - ideal para UI, pipelines y rastreos de larga duración.
|
|
- 🛡️ **Detección de Solicitudes Bloqueadas**: Detección automática y reintento de solicitudes bloqueadas con lógica personalizable.
|
|
- 🤖 **Cumplimiento de robots.txt**: Flag opcional `robots_txt_obey` que respeta las directivas `Disallow`, `Crawl-delay` y `Request-rate` con caché por dominio.
|
|
- 🧪 **Modo de Desarrollo**: Almacena las respuestas en disco en la primera ejecución y las reproduce en ejecuciones posteriores - itera sobre tu lógica de `parse()` sin volver a consultar los servidores objetivo.
|
|
- 📦 **Exportación Integrada**: Exporta resultados a través de hooks y tu propio pipeline o el JSON/JSONL integrado con `result.items.to_json()` / `result.items.to_jsonl()` respectivamente.
|
|
|
|
### Obtención Avanzada de Sitios Web con Soporte de Session
|
|
- **Solicitudes HTTP**: Solicitudes HTTP rápidas y sigilosas con la clase `Fetcher`. Puede imitar el fingerprint TLS de los navegadores, encabezados y usar HTTP/3.
|
|
- **Carga Dinámica**: Obtén sitios web dinámicos con automatización completa del navegador a través de la clase `DynamicFetcher` compatible con Chromium de Playwright y Google Chrome.
|
|
- **Evasión Anti-bot**: Capacidades de sigilo avanzadas con `StealthyFetcher` y falsificación de fingerprint. Puede evadir fácilmente todos los tipos de Turnstile/Interstitial de Cloudflare con automatización.
|
|
- **Gestión de Session**: Soporte de sesión persistente con las clases `FetcherSession`, `StealthySession` y `DynamicSession` para la gestión de cookies y estado entre solicitudes.
|
|
- **Rotación de Proxy**: `ProxyRotator` integrado con estrategias de rotación cíclica o personalizadas en todos los tipos de sesión, además de sobrescrituras de Proxy por solicitud.
|
|
- **Bloqueo de Dominios y Anuncios**: Bloquea solicitudes a dominios específicos (y sus subdominios) o activa el bloqueo de anuncios integrado (~3,500 dominios de anuncios/rastreadores conocidos) en fetchers basados en navegador.
|
|
- **Prevención de Fugas DNS**: Soporte opcional de DNS-over-HTTPS para enrutar consultas DNS a través del DoH de Cloudflare, previniendo fugas DNS al usar proxies.
|
|
- **Soporte Async**: Soporte async completo en todos los fetchers y clases de sesión async dedicadas.
|
|
|
|
### Scraping Adaptativo e Integración con IA
|
|
- 🔄 **Seguimiento Inteligente de Elementos**: Relocaliza elementos después de cambios en el sitio web usando algoritmos inteligentes de similitud.
|
|
- 🎯 **Selección Flexible Inteligente**: Selectores CSS, selectores XPath, búsqueda basada en filtros, búsqueda de texto, búsqueda regex y más.
|
|
- 🔍 **Encontrar Elementos Similares**: Localiza automáticamente elementos similares a los elementos encontrados.
|
|
- 🤖 **Servidor MCP para usar con IA**: Servidor MCP integrado para Web Scraping asistido por IA y extracción de datos. El servidor MCP presenta capacidades potentes y personalizadas que aprovechan Scrapling para extraer contenido específico antes de pasarlo a la IA (Claude/Cursor/etc), acelerando así las operaciones y reduciendo costos al minimizar el uso de tokens. ([video demo](https://www.youtube.com/watch?v=qyFk3ZNwOxE))
|
|
|
|
### Arquitectura de Alto Rendimiento y Probada en Batalla
|
|
- 🚀 **Ultrarrápido**: Rendimiento optimizado que supera a la mayoría de las bibliotecas de Web Scraping de Python.
|
|
- 🔋 **Eficiente en Memoria**: Estructuras de datos optimizadas y carga diferida para una huella de memoria mínima.
|
|
- ⚡ **Serialización JSON Rápida**: 10 veces más rápido que la biblioteca estándar.
|
|
- 🏗️ **Probado en batalla**: Scrapling no solo tiene una cobertura de pruebas del 92% y cobertura completa de type hints, sino que ha sido utilizado diariamente por cientos de Web Scrapers durante el último año.
|
|
|
|
### Experiencia Amigable para Desarrolladores/Web Scrapers
|
|
- 🎯 **Shell Interactivo de Web Scraping**: Shell IPython integrado opcional con integración de Scrapling, atajos y nuevas herramientas para acelerar el desarrollo de scripts de Web Scraping, como convertir solicitudes curl a solicitudes Scrapling y ver resultados de solicitudes en tu navegador.
|
|
- 🚀 **Úsalo directamente desde la Terminal**: Opcionalmente, ¡puedes usar Scrapling para hacer scraping de una URL sin escribir ni una sola línea de código!
|
|
- 🛠️ **API de Navegación Rica**: Recorrido avanzado del DOM con métodos de navegación de padres, hermanos e hijos.
|
|
- 🧬 **Procesamiento de Texto Mejorado**: Métodos integrados de regex, limpieza y operaciones de cadena optimizadas.
|
|
- 📝 **Generación Automática de Selectores**: Genera selectores CSS/XPath robustos para cualquier elemento.
|
|
- 🔌 **API Familiar**: Similar a Scrapy/BeautifulSoup con los mismos pseudo-elementos usados en Scrapy/Parsel.
|
|
- 📘 **Cobertura Completa de Tipos**: Type hints completos para excelente soporte de IDE y autocompletado de código. Todo el código fuente se escanea automáticamente con **PyRight** y **MyPy** en cada cambio.
|
|
- 🔋 **Imagen Docker Lista**: Con cada lanzamiento, se construye y publica automáticamente una imagen Docker que contiene todos los navegadores.
|
|
|
|
## Primeros Pasos
|
|
|
|
Aquí tienes un vistazo rápido de lo que Scrapling puede hacer sin entrar en profundidad.
|
|
|
|
### Uso Básico
|
|
Solicitudes HTTP con soporte de sesión
|
|
```python
|
|
from scrapling.fetchers import Fetcher, FetcherSession
|
|
|
|
with FetcherSession(impersonate='chrome') as session: # Usa la última versión del fingerprint TLS de Chrome
|
|
page = session.get('https://quotes.toscrape.com/', stealthy_headers=True)
|
|
quotes = page.css('.quote .text::text').getall()
|
|
|
|
# O usa solicitudes de una sola vez
|
|
page = Fetcher.get('https://quotes.toscrape.com/')
|
|
quotes = page.css('.quote .text::text').getall()
|
|
```
|
|
Modo sigiloso avanzado
|
|
```python
|
|
from scrapling.fetchers import StealthyFetcher, StealthySession
|
|
|
|
with StealthySession(headless=True, solve_cloudflare=True) as session: # Mantén el navegador abierto hasta que termines
|
|
page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False)
|
|
data = page.css('#padded_content a').getall()
|
|
|
|
# O usa el estilo de solicitud de una sola vez, abre el navegador para esta solicitud, luego lo cierra después de terminar
|
|
page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare')
|
|
data = page.css('#padded_content a').getall()
|
|
```
|
|
Automatización completa del navegador
|
|
```python
|
|
from scrapling.fetchers import DynamicFetcher, DynamicSession
|
|
|
|
with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: # Mantén el navegador abierto hasta que termines
|
|
page = session.fetch('https://quotes.toscrape.com/', load_dom=False)
|
|
data = page.xpath('//span[@class="text"]/text()').getall() # Selector XPath si lo prefieres
|
|
|
|
# O usa el estilo de solicitud de una sola vez, abre el navegador para esta solicitud, luego lo cierra después de terminar
|
|
page = DynamicFetcher.fetch('https://quotes.toscrape.com/')
|
|
data = page.css('.quote .text::text').getall()
|
|
```
|
|
|
|
### Spiders
|
|
Construye rastreadores completos con solicitudes concurrentes, múltiples tipos de sesión y 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"Se extrajeron {len(result.items)} citas")
|
|
result.items.to_json("quotes.json")
|
|
```
|
|
Usa múltiples tipos de sesión en un solo 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():
|
|
# Enruta las páginas protegidas a través de la sesión sigilosa
|
|
if "protected" in link:
|
|
yield Request(link, sid="stealth")
|
|
else:
|
|
yield Request(link, sid="fast", callback=self.parse) # callback explícito
|
|
```
|
|
Pausa y reanuda rastreos largos con checkpoints ejecutando el Spider así:
|
|
```python
|
|
QuotesSpider(crawldir="./crawl_data").start()
|
|
```
|
|
Presiona Ctrl+C para pausar de forma ordenada - el progreso se guarda automáticamente. Después, cuando inicies el Spider de nuevo, pasa el mismo `crawldir`, y continuará desde donde se detuvo.
|
|
|
|
### Análisis Avanzado y Navegación
|
|
```python
|
|
from scrapling.fetchers import Fetcher
|
|
|
|
# Selección rica de elementos y navegación
|
|
page = Fetcher.get('https://quotes.toscrape.com/')
|
|
|
|
# Obtén citas con múltiples métodos de selección
|
|
quotes = page.css('.quote') # Selector CSS
|
|
quotes = page.xpath('//div[@class="quote"]') # XPath
|
|
quotes = page.find_all('div', {'class': 'quote'}) # Estilo BeautifulSoup
|
|
# Igual que
|
|
quotes = page.find_all('div', class_='quote')
|
|
quotes = page.find_all(['div'], class_='quote')
|
|
quotes = page.find_all(class_='quote') # y así sucesivamente...
|
|
# Encuentra elementos por contenido de texto
|
|
quotes = page.find_by_text('quote', tag='div')
|
|
|
|
# Navegación avanzada
|
|
quote_text = page.css('.quote')[0].css('.text::text').get()
|
|
quote_text = page.css('.quote').css('.text::text').getall() # Selectores encadenados
|
|
first_quote = page.css('.quote')[0]
|
|
author = first_quote.next_sibling.css('.author::text')
|
|
parent_container = first_quote.parent
|
|
|
|
# Relaciones y similitud de elementos
|
|
similar_elements = first_quote.find_similar()
|
|
below_elements = first_quote.below_elements()
|
|
```
|
|
Puedes usar el parser directamente si no necesitas obtener sitios web, como se muestra a continuación:
|
|
```python
|
|
from scrapling.parser import Selector
|
|
|
|
page = Selector("<html>...</html>")
|
|
```
|
|
¡Y funciona exactamente de la misma manera!
|
|
|
|
### Ejemplos de Gestión de Session Async
|
|
```python
|
|
import asyncio
|
|
from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession
|
|
|
|
async with FetcherSession(http3=True) as session: # `FetcherSession` es consciente del contexto y puede funcionar tanto en patrones sync/async
|
|
page1 = session.get('https://quotes.toscrape.com/')
|
|
page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135')
|
|
|
|
# Uso de sesión async
|
|
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()) # Opcional - El estado del pool de pestañas del navegador (ocupado/libre/error)
|
|
results = await asyncio.gather(*tasks)
|
|
print(session.get_pool_stats())
|
|
```
|
|
|
|
## CLI y Shell Interactivo
|
|
|
|
Scrapling incluye una poderosa interfaz de línea de comandos:
|
|
|
|
[](https://asciinema.org/a/736339)
|
|
|
|
Lanzar el Shell interactivo de Web Scraping
|
|
```bash
|
|
scrapling shell
|
|
```
|
|
Extraer páginas a un archivo directamente sin programar (Extrae el contenido dentro de la etiqueta `body` por defecto). Si el archivo de salida termina con `.txt`, entonces se extraerá el contenido de texto del objetivo. Si termina con `.md`, será una representación Markdown del contenido HTML; si termina con `.html`, será el contenido HTML en sí mismo.
|
|
```bash
|
|
scrapling extract get 'https://example.com' content.md
|
|
scrapling extract get 'https://example.com' content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome' # Todos los elementos que coinciden con el selector CSS '#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]
|
|
> Hay muchas características adicionales, pero queremos mantener esta página concisa, incluyendo el servidor MCP y el Shell Interactivo de Web Scraping. Consulta la documentación completa [aquí](https://scrapling.readthedocs.io/en/latest/)
|
|
|
|
## Benchmarks de Rendimiento
|
|
|
|
Scrapling no solo es potente, también es ultrarrápido. Los siguientes benchmarks comparan el parser de Scrapling con las últimas versiones de otras bibliotecas populares.
|
|
|
|
### Prueba de Velocidad de Extracción de Texto (5000 elementos anidados)
|
|
|
|
| # | Biblioteca | Tiempo (ms) | vs Scrapling |
|
|
|---|:-----------------:|:-----------:|:------------:|
|
|
| 1 | Scrapling | 1.98 | 1.0x |
|
|
| 2 | Parsel/Scrapy | 1.99 | 1.005 |
|
|
| 3 | Raw Lxml | 2.48 | 1.253 |
|
|
| 4 | PyQuery | 23.15 | ~12x |
|
|
| 5 | Selectolax | 196.09 | ~99x |
|
|
| 6 | MechanicalSoup | 1531.24 | ~773.4x |
|
|
| 7 | BS4 with Lxml | 1535.19 | ~775.3x |
|
|
| 8 | BS4 with html5lib | 3388.16 | ~1711.2x |
|
|
|
|
|
|
### Rendimiento de Similitud de Elementos y Búsqueda de Texto
|
|
|
|
Las capacidades de búsqueda adaptativa de elementos de Scrapling superan significativamente a las alternativas:
|
|
|
|
| Biblioteca | Tiempo (ms) | vs Scrapling |
|
|
|-------------|:-----------:|:------------:|
|
|
| Scrapling | 2.29 | 1.0x |
|
|
| AutoScraper | 12.46 | 5.441x |
|
|
|
|
|
|
> Todos los benchmarks representan promedios de más de 100 ejecuciones. Ver [benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py) para la metodología.
|
|
|
|
## Instalación
|
|
|
|
Scrapling requiere Python 3.10 o superior:
|
|
|
|
```bash
|
|
pip install scrapling
|
|
```
|
|
|
|
> [!IMPORTANT]
|
|
> Esta instalación solo incluye el motor de análisis y sus dependencias, sin ningún fetcher ni dependencias de línea de comandos. Por lo tanto, importar cualquier cosa desde `scrapling.fetchers` o `scrapling.spiders`, como en los ejemplos anteriores, lanzará un `ModuleNotFoundError` solo con esta instalación. Si va a usar alguno de los fetchers o spiders, instale primero las dependencias de los fetchers como se muestra a continuación.
|
|
|
|
### Dependencias Opcionales
|
|
|
|
1. Si vas a usar alguna de las características adicionales a continuación, los fetchers, o sus clases, necesitarás instalar las dependencias de los fetchers y sus dependencias del navegador de la siguiente manera:
|
|
```bash
|
|
pip install "scrapling[fetchers]"
|
|
|
|
scrapling install # normal install
|
|
scrapling install --force # force reinstall
|
|
```
|
|
|
|
Esto descarga todos los navegadores, junto con sus dependencias del sistema y dependencias de manipulación de fingerprint.
|
|
|
|
O puedes instalarlos desde el código en lugar de ejecutar un comando:
|
|
```python
|
|
from scrapling.cli import install
|
|
|
|
install([], standalone_mode=False) # normal install
|
|
install(["--force"], standalone_mode=False) # force reinstall
|
|
```
|
|
|
|
2. Características adicionales:
|
|
- Instalar la característica del servidor MCP:
|
|
```bash
|
|
pip install "scrapling[ai]"
|
|
```
|
|
- Instalar características del Shell (Shell de Web Scraping y el comando `extract`):
|
|
```bash
|
|
pip install "scrapling[shell]"
|
|
```
|
|
- Instalar todo:
|
|
```bash
|
|
pip install "scrapling[all]"
|
|
```
|
|
Recuerda que necesitas instalar las dependencias del navegador con `scrapling install` después de cualquiera de estos extras (si no lo hiciste ya)
|
|
|
|
### Docker
|
|
También puedes instalar una imagen Docker con todos los extras y navegadores con el siguiente comando desde DockerHub:
|
|
```bash
|
|
docker pull pyd4vinci/scrapling
|
|
```
|
|
O descárgala desde el registro de GitHub:
|
|
```bash
|
|
docker pull ghcr.io/d4vinci/scrapling:latest
|
|
```
|
|
Esta imagen se construye y publica automáticamente usando GitHub Actions y la rama principal del repositorio.
|
|
|
|
## Contribuir
|
|
|
|
¡Damos la bienvenida a las contribuciones! Por favor lee nuestras [pautas de contribución](https://github.com/D4Vinci/Scrapling/blob/main/CONTRIBUTING.md) antes de comenzar.
|
|
|
|
## Descargo de Responsabilidad
|
|
|
|
> [!CAUTION]
|
|
> Esta biblioteca se proporciona solo con fines educativos y de investigación. Al usar esta biblioteca, aceptas cumplir con las leyes locales e internacionales de scraping de datos y privacidad. Los autores y contribuyentes no son responsables de ningún mal uso de este software. Respeta siempre los términos de servicio de los sitios web y los archivos robots.txt.
|
|
|
|
## 🎓 Citas
|
|
Si has utilizado nuestra biblioteca con fines de investigación, por favor cítanos con la siguiente referencia:
|
|
```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!}
|
|
}
|
|
```
|
|
|
|
## Licencia
|
|
|
|
Este trabajo está licenciado bajo la Licencia BSD-3-Clause.
|
|
|
|
## Agradecimientos
|
|
|
|
Este proyecto incluye código adaptado de:
|
|
- Parsel (Licencia BSD)-Usado para el submódulo [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py)
|
|
|
|
---
|
|
<div align="center"><small>Diseñado y elaborado con ❤️ por Karim Shoair.</small></div><br>
|