Deja de Escribir Scrapers. Nadie ha Fallado Nunca por sus Selectores CSS
Que te bloqueen en la ejecución 47 a las 3 de la mañana es lo que mata tu pipeline. No un selector roto. No una página que cambió de markup.
Nadie fracasa en web scraping porque su `document.querySelector` estuviera mal escrito. Fracasan porque el sitio objetivo detecta tu fingerprint TLS en el request 43, te sirve un 403 y tu script en bucle reintenta hasta que el VPS se queda sin memoria.
*Apify no es una empresa de scraping. Es una empresa de anti-fragilidad.* Esa distinción es toda la lección.
Y aquí está la parte que ningún tutorial te cuenta: el código de scraping — lo que todo el mundo comenta — te lo regalan gratis. Es open source. Lo que pagas es la fontanería: rotación de proxies, reintentos, escalado serverless, almacenamiento y el hecho de que tu scraper siga vivo mañana.
Vamos a construir algo real. Pero primero, derribemos la suposición equivocada.
---
El Problema: Crees que el Scraping es un Problema de Código
Hay dos mentiras circulando por ahí sobre web scraping en 2026.
La primera dice que scraping está muriendo porque la IA "ya lo sabe todo". Falso. La adopción de LLMs ha *aumentado* la demanda de datos frescos y estructurados para RAG pipelines y conjuntos de evaluación. Un modelo fundacional no puede saber el precio actual de un producto ni el estado de una oferta. Eso solo lo da un scraper que corre hoy.
La segunda mentira dice que scraping es trivial: un bucle `for` sobre URLs con una librería de selectores.
Eso funciona exactamente hasta la primera página que te bloquea.
El cuello de botella se desplazó. Ya no es "conseguir el HTML". Es mantener el pipeline vivo a escala contra defensas anti-bot que fingerprintean tu TLS, throttlean tu concurrencia y te sirven honeypots que parecen datos reales.
El código nunca fue el problema. *La resiliencia es el problema.* Y esa es exactamente el área que Apify construyó alrededor de un core open source llamado Crawlee.
---
La Evidencia: el Scraper que Gana Nunca se Ejecuta en tu Portátil
Miremos el boilerplate. Un scraper ingenuo con `axios` + `cheerio`:
```javascript
// scraper_naive.js — muere en el primer 403
const axios = require('axios');
const cheerio = require('cheerio');
const urls = ['https://ejemplo.com/a', 'https://ejemplo.com/b'];
for (const url of urls) {
const { data } = await axios.get(url); // → 403 en producción, sin reintento
const $ = cheerio.load(data);
const titulo = $('h1').text();
console.log(titulo);
}
```
Cinco líneas. Funciona en local. Y se rompe en producción cuando el sitio detecta que no hay sesión, que no hay headers reales de navegador, que el ritmo de requests es de bot.
Ahora el mismo objetivo con Crawlee en Node:
```javascript
// crawlee_scraper.js — sobrevive a producción
import { CheerioCrawler } from 'crawlee';
const crawler = new CheerioCrawler({
maxRequestsPerCrawl: 100,
maxConcurrency: 10,
// Session pool: rotación de identidad + reintentos automáticos
useSessionPool: true,
sessionPoolOptions: {
maxPoolSize: 50,
blockedStatusCodes: [403, 429], // detecta bloqueo → gira sesión
},
requestHandler: async ({ request, $ }) => {
await crawler.pushData({
url: request.url,
titulo: $('h1').text().trim(),
fecha: $('time').attr('datetime'),
});
},
});
await crawler.run(['https://ejemplo.com/listado']);
```
La diferencia no son los selectores. Son ~15 líneas de configuración que gestionan reintentos, detección de bloqueo y salida estructurada a dataset.
*Eso es el valor de Crawlee: no es lo que raspa. Es lo que ya no tienes que escribir tú.*
El mismo patrón existe en Python. Para objetivos con mucho JavaScript, usas el `PlaywrightCrawler`, que levanta un navegador headless con un session pool consolidado. Intentar eso a mano — con Playwright crudo y lógica manual de waits — es semanas de debugging que nadie te agradece.
Y aquí está la decisión estratégica que casi nadie analiza: Apify renombró su SDK a Crawlee en 2022 y lo liberó como open source con un nombre neutral. No es caridad. Es que el foso no está en el código — que cualquiera puede forkear — sino en la capa de operación: inventario de proxies, uptime, scheduling, almacenamiento y tooling de compliance.
Regalaron el cebo. Venden la fontanería.
---
El Análisis: el Modelo de Actors es Serverless con Entrada y Salida Tipadas
Aquí es donde el tutorial se separa del chiste. Porque un "Actor" en Apify no es "código subido a la nube". Es un cambio de mentalidad:
*Un scraper deja de ser un script y se convierte en un microservicio serverless con contrato de entrada, contrato de salida y ciclo de vida.*
Envolver tu crawler con el patrón Actor:
```javascript
// main.js — el mismo código corre en local y en la nube
import { Actor } from 'apify';
import { CheerioCrawler } from 'crawlee';
await Actor.main(async () => {
const input = await Actor.getInput(); // viene del INPUT_SCHEMA
const { urls, maxItems } = input;
const crawler = new CheerioCrawler({
maxRequestsPerCrawl: maxItems,
requestHandler: async ({ request, $ }) => {
await Actor.pushData({
url: request.url,
titulo: $('h1').text().trim(),
});
},
});
await crawler.run(urls);
console.log('Actor completado.');
});
```
Con un `INPUT_SCHEMA.json` que declara qué acepta tu Actor:
```json
{
"title": "Raspador de ejemplo",
"type": "object",
"properties": {
"urls": { "type": "array", "items": { "type": "string" } },
"maxItems": { "type": "integer", "minimum": 1, "maximum": 1000 }
},
"required": ["urls"]
}
```
Ejecutas eso con `apify run` en local. Cuando funciona, haces `apify push` y el mismo código corre en un runtime serverless de Apify — escalando, con retries y con los resultados escritos en un dataset acoplado.
Ya no es un script. *Es una pieza componible en un sistema más grande.*
---
El Análisis (II): la Ola LLM le Dio la Vuelta a la Narrativa
Apify pasó de "raspamos webs" a "alimentamos modelos y agentes de IA". Ese giro no es cosmético. Es real, y cambia cómo deberías arquitecturar tus outputs.
Tres razones concretas:
1. Los sistemas RAG necesitan datos actuales que ningún periodo de entrenamiento de un modelo fundacional puede tener.
2. Los conjuntos de evaluación necesitan ground truth capturado hoy — no datos de hace seis meses.
3. Los frameworks de agentes permiten que un LLM invoque un scraper como tool a mitad de tarea.
La consecuencia práctica: en 2026, raspas para que un agente o un pipeline de datos consuma tu output. Eso significa JSON limpio y con esquema definido gana a HTML bonito, siempre.
Los tutoriales clásicos de scraping te enseñan a guardar el HTML crudo. El futuro es un Actor que devuelve schema-shaped JSON que un LLM puede parsear sin instrucciones adicionales.
---
El Framework de los 5 Movimientos del Actor
Vale, vamos a cortar el rollo teórico. Este es el Framework de los 5 Movimientos del Actor — el método único de operador que uso para cualquier recolector nuevo.
Paso 1: Forkea antes de escribir código
Busca en el Apify Store un Actor que se aproxime a tu objetivo. No reedites la rueda.
Los source code de los Actors del Store son open source. Clónalos en un proyecto local de Crawlee, inspecciona su `INPUT_SCHEMA` y entiende qué hacen antes de escribir una sola línea.
La ruta típica de 2026 es: reusar → forkear → customizar → desplegar. No empezar de cero.
Paso 2: Construye y estresa en local con Crawlee
Elige tu tipo de crawler deliberadamente:
CheerioCrawler para páginas estáticas rápidas
Playwright/PuppeteerCrawler solo donde el renderizado sea imprescindible
Activa siempre el session pool y configura la lógica de reintentos. Asume que el objetivo te va a bloquear. No lo asumas cuando ocurra.
Paso 3: Convierte el script en Actor
Envuélvelo en `Actor.main()`, declara el `INPUT_SCHEMA` (URLs, selectores, límites) y el output (dataset + key-value store). Prueba end-to-end con `apify run` en local.
Configura la compliance desde el día uno — respeta `robots.txt` y limita con `maxRequestsPerCrawl`:
```javascript
// Defiende tu reputación de IP desde la primera ejecución
const crawler = new CheerioCrawler({
maxRequestsPerCrawl: 500,
maxConcurrency: 5,
// Política cortés: no impactes al objetivo
});
```
Paso 4: Despliega y operacionaliza
`apify push` a la nube. Conecta el scheduling y monitoriza la tasa de requests bloqueados. Si ese número sube, quieres saberlo tú — antes de que lo note tu consumidor downstream.
Paso 5: Diseña para el pipeline de IA
Exponer el Actor terminado como API o tool invocable — mediante la API de Apify, una integración con LangChain o una definición de tool para un agente.
```javascript
// Un agente LLM llama a otro Actor como tool
// Esto convierte el scraping en una tool-call dentro del loop del agente
const resultado = await Actor.call('tu-usuario/raspador-ejemplo', {
urls: ['https://ejemplo.com/productos'],
maxItems: 20,
});
// resultado.dataset → JSON esquematizado, listo para el LLM
```
Trata el scraper como un microservicio de datos, no como un script de un solo uso. Esa es la mentalidad más a prueba de futuro que puedes adoptar.
---
Las Objeciones que te Estás Planteando Ahora
"¿Y por qué no ejecuto Scrapy en mi propio VPS?"
Para trabajos pequeños de un solo uso, self-hosting está genial. Dicho sin rodeos. Pero hay un impuesto operativo oculto: rotación de proxies, reputación de IP, backoff de reintentos, scheduling, durabilidad de almacenamiento y monitoring — todo se convierte en tu problema.
El cálculo cambia cuando necesitas recolección continua y resiliente. Ahí es donde un VPS barato te cuesta más en horas de operación de lo que ahorras en infraestructura.
"Si hay cientos de Actors listos en el Store, ¿para qué escribir código?"
Los Actors listos son un punto de partida, no una línea de meta. Los objetivos cambian su markup y su postura anti-bot en semanas. Necesitarás selectores custom, manejo de paginación, flujos de autenticación o reshaping de output.
El código open source es el producto real: forkéalo, adáptalo y solo paga por la operación.
"¿No es scraping una violación de términos de servicio o GDPR?"
Abordemos esto sin ambigüedad:
`robots.txt` y Términos de Servicio no son lo mismo que la ley
Los datos personales activan obligaciones de GDPR independientemente de la herramienta
Apify incluye utilidades de cumplimiento con `robots.txt` y guías
Trata el scraping como una práctica de ingeniería defendible con guardarraíles. No como un hack de sombrero gris. Respeta `robots.txt`, limita tu tasa, no recolectes datos personales sin base legal — y estarás construyendo algo que sobrevive tanto a auditores como a GitHub Issues.
---
El Resumen que te Llevas
El scraping no es un problema de selectores CSS. Es un problema de orquestación anti-frágil.
Crawlee es el cerebro open source que gestiona sesiones, reintentos y detección de bloqueo. Apify es la capa de operación que ejecuta ese código como un Actor serverless — con scheduling, almacenamiento y escalado que nunca se ejecuta en tu portátil.
Los cinco movimientos: forkear el Store → estresar en local → envolver como Actor → desplegar con monitoring → exponerlo como data microservice para tu pipeline de IA.
La empresa que tiene scraping como operación, no como código, es la que gana cuando el objetivo cambia su markup a las 2 de la madrugada.
Construye el scraper que sobreviva a la ejecución 47. Porque esa ejecución va a llegar — la única pregunta es si tu pipeline la atraviesa en pie.
Lee el artículo completo en brianmenagomez.com
Más sobre mis servicios en brianmenagomez.com
Herramientas: Conversor IAE CNAE · Gestorias cerca de ti · Calculadora IRPF

