Scraping de un sitio web dinámico
Los sitios web dinámicos cargan contenido mediante JavaScript después de la carga inicial de la página. Esta guía muestra cómo recopilar datos de estos sitios utilizando el endpoint de navegador de FourA.
El problema
Cuando envía una request HTTP estándar a un sitio web con mucho JavaScript, obtiene la estructura HTML pero no el contenido real. Los datos que necesita (listas de productos, precios, resultados de búsqueda) se cargan mediante JavaScript después de que la página se renderiza en un navegador.
Esto es cada vez más común con frameworks modernos como React, Vue, Angular y Next.js.
La solución: Requests de navegador
El endpoint de navegador de FourA (POST /api/browser/) abre su URL en una instancia de navegador Chrome que:
- Carga la página
- Ejecuta todo el JavaScript
- Espera a que se renderice el contenido
- Devuelve el HTML completamente renderizado
Paso 1: Identifique lo que necesita
Antes de realizar la request, visite la página de destino en su navegador y use las DevTools (F12) para buscar un fragmento de texto o un elemento que confirme que el contenido se ha cargado. Por ejemplo:
- Un nombre de producto que aparece después de que se renderiza el JS
- Una clase CSS como
product-griden el HTML renderizado - Una cadena de texto como "results" que solo aparece cuando se cargan los datos
Paso 2: Envíe una request de navegador
curl -X POST https://eu.api.foura.ai/api/browser/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/products",
"timeout_ms": 15000,
"checkText": "product-grid"
}'
La opción checkText le indica a FourA que verifique que la cadena "product-grid" aparezca en la página renderizada. Si no aparece antes del tiempo de espera, la request falla, lo que le permite saber que el contenido no se cargó.
Paso 3: Analice el HTML
La response contiene el HTML completamente renderizado en el campo body. Analícelo con su biblioteca preferida:
Python (BeautifulSoup)
import requests
from bs4 import BeautifulSoup
resp = requests.post("https://eu.api.foura.ai/api/browser/", headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
}, json={
"url": "https://example.com/products",
"timeout_ms": 15000,
"checkText": "product-grid"
})
html = resp.json()["body"]
soup = BeautifulSoup(html, "html.parser")
for product in soup.select(".product-card"):
name = product.select_one(".product-name").text.strip()
price = product.select_one(".product-price").text.strip()
print(f"{name}: {price}")
Node.js (cheerio)
import * as cheerio from 'cheerio';
const resp = await fetch('https://eu.api.foura.ai/api/browser/', {
method: 'POST',
headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({
url: 'https://example.com/products',
timeout_ms: 15000,
checkText: 'product-grid'
})
});
const { body: html } = await resp.json();
const $ = cheerio.load(html);
$('.product-card').each((i, el) => {
console.log($(el).find('.product-name').text(), $(el).find('.product-price').text());
});
Solución de problemas
¿Sigue obteniendo contenido vacío?
- Verifique que la página realmente utilice renderizado de JavaScript (compare "Ver código fuente de la página" con DevTools)
- Aumente
timeout_ms: algunas páginas se cargan lentamente - Compruebe si la página requiere autenticación o cookies (use el parámetro
cookies)
¿Aparece una página de captcha?
- Para requests individuales/HTTP, cambie al endpoint de proxy (
POST /api/proxy/) para obtener rotación automática de IP. - Para agregar rotación de proxy a las requests de navegador, use el parámetro
proxydel endpoint de navegador en lugar de envolverlo en el endpoint de proxy. El endpoint de proxy solo envuelve requests individuales/HTTP, no requests de navegador.
curl -X POST "https://eu.api.foura.ai/api/browser/" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "proxy": "http://proxy-url:port"}'
Próximos pasos
- Elegir el endpoint correcto: Cuándo usar browser frente a single
- Monitorear precios de competidores: Tutorial completo de seguimiento de precios
- Protección anti-bot: Cómo manejar sitios protegidos