Tienes que extraer datos de un sitio web para un proyecto: precios de la competencia, ofertas de empleo, artículos técnicos o métricas públicas. Abres la terminal, instalas requests y BeautifulSoup… y a los pocos días el sitio cambió su estructura HTML y tu script quedó inservible. Peor aún: el sitio te bloqueó la IP por hacer demasiadas peticiones en segundos.
Este escenario se repite todos los días. El web scraping en 2026 no se trata solo de saber programar: se trata de hacerlo de forma ética, legal y sostenible. Y la herramienta que domina el campo ya no es un simple requests.get(), sino Playwright con Python.
Primero lo primero: la parte legal
Antes de escribir una sola línea de código, entiende qué puedes y qué no puedes extraer. El scraping no es ilegal por sí mismo — los buscadores hacen exactamente eso — pero sí lo es cuando violas normas específicas:
robots.txt: es el punto de partida. Indica qué rutas permite el sitio para bots. Si diceDisallow: /private/, respétalo. No es una ley, pero ignorarlo es la primera señal de alerta para los equipos de seguridad del sitio.- Términos de servicio (ToS): muchos sitios prohíben el scraping en sus términos, aunque los datos sean públicos. En varios países, incumplir el ToS puede derivar en demandas civiles, como han demostrado los casos de LinkedIn vs. hiQ y Meta vs. Bright Data.
- Datos personales: si lo que extraes incluye información de personas (emails, nombres, teléfonos), entras en terreno de protección de datos. En Europa rige el GDPR y en LATAM leyes como la Ley 29733 en Perú o la Ley Federal de Protección de Datos en México. Extraer datos personales sin consentimiento ni finalidad legítima te expone a sanciones millonarias.
- Alternativa preferida: si el sitio ofrece API oficial, úsala. Siempre. Una API pública es la forma más ética y estable de obtener datos; el scraping queda como último recurso.
“El scraping ético no es una limitación: es lo que separa una herramienta profesional de un script que te puede meter en problemas.”
Por qué Playwright reemplazó a requests + BeautifulSoup
Durante años el stack clásico fue requests + BeautifulSoup. Funciona para sitios estáticos, pero en 2026 casi todo el contenido relevante se renderiza con JavaScript: React, Vue, Angular, infinite scroll, dashboards. requests solo obtiene el HTML inicial, vacío de datos.
Playwright resuelve esto ejecutando un navegador real (Chromium, Firefox o WebKit) en modo headless:
- Renderiza JavaScript y espera a que el contenido aparezca con
wait_for_selector(). - Permite hacer clic, llenar formularios, hacer scroll infinito y capturar redes.
- Genera selectores robustos y tolera cambios menores en el DOM.
- Soporta async nativo y es rápido con navegadores persistentes.
Alternativas válidas: Scrapy (ideal para crawlers masivos con pipelines de datos), Selenium (legacy, más lento) y Puppeteer (el equivalente en Node.js). Pero para proyectos Python donde necesitas un navegador real, Playwright es la opción más equilibrada.
El patrón ético: 5 reglas de oro
Antes de implementar, interioriza estas reglas. Son el estándar de facto en la industria:
- Consulta
robots.txty respetaCrawl-delaysi existe. - Identifícate: usa un
User-Agentreal y unRefererhonesto. No te hagas pasar por navegador de Google. - Limita la velocidad: entre 3 y 10 segundos entre peticiones al mismo dominio. Eres un invitado, no un DDoS.
- Reduce el volumen: extrae solo lo necesario, no todo el sitio “por si acaso”.
- Cachea localmente: si ya descargaste un recurso, no lo vuelvas a pedir. Menos carga para el servidor y menos riesgo para ti.
Implementación paso a paso con Playwright
Vamos a la práctica. Este patrón extrae artículos de un blog respetando las reglas éticas:
import asyncio
import json
import random
from playwright.async_api import async_playwright
BASE_URL = "https://ejemplo.com/blog"
SELECTOR_ARTICULOS = "article h2 a"
async def extraer_articulos():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
# 1. Navegador persistente con User-Agent honesto
context = await browser.new_context(
user_agent="MiScraper/1.0 (+https://miproducto.com; contacto@miproducto.com)"
)
page = await context.new_page()
# 2. Espera el contenido renderizado
await page.goto(BASE_URL, wait_until="domcontentloaded")
await page.wait_for_selector(SELECTOR_ARTICULOS, timeout=15000)
# 3. Extrae los enlaces
enlaces = await page.eval_on_selector_all(
SELECTOR_ARTICULOS,
"els => els.map(e => ({ titulo: e.textContent.trim(), url: e.href }))"
)
# 4. Rate limiting: espera aleatoria entre 3 y 7 segundos
await asyncio.sleep(random.uniform(3, 7))
await browser.close()
return enlaces
async def main():
datos = await extraer_articulos()
with open("articulos.json", "w", encoding="utf-8") as f:
json.dump(datos, f, ensure_ascii=False, indent=2)
print(f"Extraídos {len(datos)} artículos")
asyncio.run(main())
Observa los detalles clave: el User-Agent honesto (identificable y con contacto), el wait_for_selector en lugar de sleeps fijos (más robusto), y el delay aleatorio que simula un ritmo humano sin saturar el servidor.
Para producción, añade tres piezas más: retry con backoff exponencial para errores 429/5xx, rotación de proxies solo si es legítimo (no para evadir bloqueos), y logging estructurado para auditar qué extrajiste y cuándo. Así, si el sitio te contacta, puedes demostrar que tu scraping fue responsable.
Errores comunes y cómo evitarlos
| Error | Causa | Solución |
|---|---|---|
| Script roto a los días | Selectores frágiles o cambios de layout | Usar selectores por texto/rol y validar con tests |
| IP bloqueada | Demasiadas peticiones en poco tiempo | Rate limiting estricto + reintentos con backoff |
| Captcha o Cloudflare | Comportamiento detectado como bot | Reducir velocidad, usar navegador persistente real |
| Datos incompletos | Scroll infinito sin cargar | Hacer scroll incremental y esperar nuevos nodos |
| Problemas legales | Extraer datos personales sin base legal | Consultar con un abogado antes de escalar |
El error más costoso no es técnico, es jurídico. Documenta tu scraping: qué extraes, por qué, a qué velocidad y con qué finalidad. Esa documentación te protege y demuestra buena fe.
El futuro: scraping aumentado con IA
En 2026, la frontera está en combinar scraping con agentes de IA: en lugar de selectores rígidos, un modelo multimodal observa la página, identifica los datos relevantes y los estructura. Los selectores siguen siendo más predecibles, pero la IA está volviendo los scrapers mucho más resistentes a cambios de diseño — y también está creando una nueva generación de scrapers más cuidadosos, que entienden el contexto y respetan mejor los límites del sitio.
El web scraping ético no es contradictorio: es la única forma profesional de hacerlo. Respeta robots.txt, limita tu velocidad, identifícate y usa Playwright para manejar la web moderna. Con ese patrón, tus extractores de datos durarán meses en lugar de días — y sin sustos legales.
¿Tienes un proyecto de scraping en mente o ya has tenido que lidiar con bloqueos de IP? Sigue explorando estos temas en el blog de DojoFullStack, donde compartimos guías prácticas de automatización, agentes de código y desarrollo de software moderno.
Si quieres dominar Python, Playwright y las herramientas de automatización que usan los equipos reales, el blog de DojoFullStack tiene contenido semanal que te ayudará a construir tu caja de herramientas de ingeniería potenciada por IA.