Scraper un site dynamique
Les sites web dynamiques chargent du contenu via JavaScript après le chargement initial de la page. Ce guide explique comment collecter des données à partir de ces sites en utilisant l'endpoint de navigateur de FourA.
Le Problème
Lorsque vous envoyez une requête HTTP standard à un site web riche en JavaScript, vous obtenez la structure HTML de base, mais pas le contenu réel. Les données dont vous avez besoin (listes de produits, prix, résultats de recherche) sont chargées par JavaScript après le rendu de la page dans un navigateur.
Ce comportement est de plus en plus courant avec les frameworks modernes tels que React, Vue, Angular et Next.js.
La Solution : Requêtes de Navigateur
L'endpoint de navigateur de FourA (POST /api/browser/) ouvre votre URL dans une instance de navigateur Chrome qui :
- Charge la page
- Exécute l'ensemble du JavaScript
- Attend le rendu du contenu
- Renvoie le code HTML entièrement rendu
Étape 1 : Identifiez ce dont vous avez besoin
Avant d'effectuer la requête, consultez la page cible dans votre navigateur et utilisez les DevTools (F12) pour repérer un texte ou un élément confirmant que le contenu est chargé. Par exemple :
- Un nom de produit qui apparaît après le rendu JS
- Une classe CSS comme
product-griddans le HTML rendu - Une chaîne de texte telle que "results" qui n'apparaît que lors du chargement des données
Étape 2 : Envoyer une requête de navigateur
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"
}'
L'option checkText indique à FourA de vérifier que "product-grid" est présent sur la page une fois son chargement terminé. Si ce n'est pas le cas, la request renvoie un échec avec checkText:product-grid not found, et une request ayant échoué n'est pas facturée. checkText ne prolonge pas l'attente de FourA pour le texte.
Étape 3 : Parser le HTML
La response contient le HTML entièrement rendu dans le champ body. Analysez-le avec votre bibliothèque préférée :
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());
});
Dépannage
Vous obtenez toujours un contenu vide ?
- Vérifiez que la page utilise bien le rendu JavaScript (comparez le « Code source de la page » avec les DevTools)
- Augmentez
timeout_ms: certaines pages se chargent lentement - Vérifiez si la page nécessite une authentification ou des cookies (utilisez le paramètre
cookies)
Vous rencontrez une page de vérification ?
- Pour les requêtes HTTP uniques, basculez vers l'endpoint proxy (
POST /api/proxy/) pour bénéficier d'une rotation automatique d'IP. - Pour router une requête de navigateur via un proxy, transmettez le paramètre
proxyde l'endpoint browser. L'endpoint proxy prend uniquement en charge les requêtes HTTP simples, pas les requêtes de navigateur.
Le paramètre proxy accepte l'identifiant de proxy opaque renvoyé par une réponse précédente, jamais votre propre adresse de proxy. Exécutez d'abord un appel POST /api/proxy/ (ou POST /api/auto/), lisez le champ proxy retourné, puis épinglez-le :
# Step 1: let FourA find a working exit. The response carries "proxy": "A1B2C3".
curl -X POST "https://eu.api.foura.ai/api/proxy/" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"maxTries": 5, "request": {"method": "GET", "url": "https://example.com/products"}}'
# Step 2: render through that same exit.
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", "proxy": "A1B2C3", "timeout_ms": 20000}'
Envoyer une adresse au lieu d'un ID renvoie 400 Invalid proxy format. Le modèle complet se trouve dans Réutiliser un proxy sur plusieurs requêtes.
Prochaines étapes
- Choisir le bon endpoint : Quand utiliser browser vs. single
- Surveiller les prix des concurrents : Tutoriel complet de suivi des prix
- Sites protégés : Gérer les sites protégés
- Réutiliser un proxy sur plusieurs requêtes : Conserver une même sortie sur l'ensemble d'un workflow