← Tous les articles

Appelez N'importe Quel Plugin ScrapeUnblocker Depuis Python, Node.js, PHP ou Ruby

Les plugins sont le moyen le plus rapide d’obtenir des données structurées depuis un site précis. Vous envoyez un mot-clé ou un identifiant et vous recevez un JSON propre, sans sélecteurs à maintenir. La seule question a toujours été la quantité de code de liaison entre votre projet et ce JSON.

Depuis le SDK 0.11.0, il en faut très peu. Les clients Python, Node.js, PHP et Ruby ont une méthode pour chaque plugin public, plus un appel générique pour n’importe quel endpoint de plugin. Ce guide montre comment fonctionnent les méthodes, détaille un petit script qui interroge plusieurs enseignes et couvre ce qui compte dès qu’il tourne de façon planifiée : la concurrence et la gestion des erreurs.

Ce Qui a Changé

Trois nouveautés sont arrivées en même temps :

  • Une méthode pour chaque plugin dans les quatre SDK. La vue d’ensemble des plugins liste désormais plus de 60 plugins dans 14 catégories : e-commerce, alimentation, voyage, Google, autres moteurs de recherche, immobilier, véhicules, emploi, avis, commerces locaux, applications, vidéo et musique, SEO et publicité. Chacun a sa méthode.
  • Une page de documentation par plugin. Chaque page liste les champs, montre un exemple de réponse et présente l’appel en cURL, Python, Node.js, PHP et Ruby côte à côte.
  • Les plugins dans le serveur MCP. Le serveur MCP et le connecteur hébergé gagnent deux outils, list_plugins et run_plugin, pour qu’un assistant IA puisse trouver et lancer les mêmes plugins.

Installer le SDK

Choisissez votre langage :

pip install scrapeunblocker              # Python 3.8+
npm install scrapeunblocker              # Node.js 18+
composer require scrapeunblocker/client  # PHP 8.1+
gem install scrapeunblocker              # Ruby 2.7+

Placez ensuite votre clé API dans une variable d’environnement. Les quatre clients la lisent automatiquement :

export SCRAPEUNBLOCKER_KEY="YOUR_API_KEY"

Vous obtenez la clé dans le tableau de bord. Si un SDK est déjà installé, passez à la version 0.11.0 ou ultérieure pour disposer de toutes les méthodes de plugins.

Comment Fonctionnent les Méthodes de Plugin

Le principe est le même dans tous les langages. Une fois que vous avez utilisé un plugin, vous savez les utiliser tous :

  • La méthode porte le nom du plugin. Walmart Search devient walmart_search en Python et en Ruby, et walmartSearch en Node.js et en PHP.
  • L’entrée principale vient en premier. Un mot-clé, un identifiant de produit ou un domaine est le premier argument.
  • Tout le reste est une option. Des arguments nommés en Python et en Ruby, un objet d’options en Node.js (clés en camelCase), un tableau indexé par les noms de paramètres de l’API en PHP.
  • Les options omises ne sont pas envoyées. Les valeurs par défaut de l’API s’appliquent, vous ne passez donc que ce que vous voulez changer.
  • Les listes sont gérées pour vous. Quand un plugin accepte plusieurs valeurs, passez une liste et le SDK l’envoie séparée par des virgules.

Voici la même recherche Best Buy dans les quatre langages :

# Python
result = su.bestbuy_search("laptop", sort="price_low", max_results=48)
// Node.js
const result = await su.bestbuySearch("laptop", { sort: "price_low", maxResults: 48 });
// PHP
$result = $su->bestbuySearch('laptop', ['sort' => 'price_low', 'max_results' => 48]);
# Ruby
result = su.bestbuy_search("laptop", sort: "price_low", max_results: 48)

Dans chaque cas, su est le client : Client() en Python, new ScrapeUnblockerClient() en Node.js, new Client() en PHP et ScrapeUnblocker::Client.new en Ruby.

Exemple : Comparer les Prix de Trois Enseignes

Un bon premier projet consiste à comparer les prix entre plusieurs magasins. Walmart, Target et Best Buy ont chacun un plugin de recherche, et les trois acceptent les mêmes options sort="price_low" et max_results. Leurs réponses, en revanche, ne sont pas identiques. Chaque plugin renvoie les champs que le site utilise lui-même :

  • Walmart appelle le nom du produit name, son identifiant id et l’ancien prix wasPrice.
  • Target utilise title et son propre identifiant produit, tcin.
  • Best Buy utilise title, sku et originalPrice, et ajoute un numéro de model.

Un champ sans valeur est entièrement absent du produit concerné. La première étape consiste donc à ramener les trois formats à un seul :

from scrapeunblocker import Client

su = Client()  # reads SCRAPEUNBLOCKER_KEY
QUERY = "wireless headphones"

def normalize(store, item):
    return {
        "store": store,
        "id": item.get("id") or item.get("tcin") or item.get("sku"),
        "title": item.get("name") or item.get("title"),
        "brand": item.get("brand") or "",
        "price": item.get("price"),
        "regular_price": item.get("wasPrice") or item.get("originalPrice"),
        "url": item.get("url"),
    }

stores = {
    "walmart": su.walmart_search,
    "target": su.target_search,
    "bestbuy": su.bestbuy_search,
}

rows = []
for store, search in stores.items():
    result = search(QUERY, sort="price_low", max_results=48)
    rows += [normalize(store, p) for p in result.get("products", [])]

sony = [r for r in rows if r["brand"].lower() == "sony" and r["price"]]
for r in sorted(sony, key=lambda r: r["price"])[:10]:
    print(f'{r["store"]:8} {r["price"]:>8.2f}  {r["title"][:60]}')

Trois appels, un tableau, et chaque ligne avec l’enseigne, le prix et le lien. Enregistrez ces lignes en base une fois par jour et vous obtenez un historique des prix.

Une mise en garde honnête : la difficulté n’est pas le scraping, mais le rapprochement du même produit d’une enseigne à l’autre. Les titres diffèrent d’un magasin à l’autre. La marque associée au numéro de modèle est une bien meilleure clé que le titre, et Best Buy fournit directement model. Prévoyez un peu de rapprochement manuel pour vos produits les plus importants.

Lancer des Appels en Parallèle Sans Recevoir de 429

Dès que vous suivez plus de quelques mots-clés, les appels séquentiels deviennent lents. En Python, chaque méthode a son équivalent asynchrone sur AsyncClient, et en Node.js chaque méthode renvoie une promesse. Limitez le nombre d’appels simultanés avec un sémaphore :

import asyncio
from scrapeunblocker import AsyncClient

QUERIES = ["wireless headphones", "air fryer", "robot vacuum", "4k tv"]
STORES = ["walmart", "target", "bestbuy"]
CONCURRENCY = 10  # keep this below your plan's concurrency limit

async def search(su, sem, store, query):
    async with sem:
        method = getattr(su, f"{store}_search")
        return store, query, await method(query, max_results=48)

async def main():
    sem = asyncio.Semaphore(CONCURRENCY)
    async with AsyncClient() as su:
        jobs = [search(su, sem, s, q) for s in STORES for q in QUERIES]
        return await asyncio.gather(*jobs, return_exceptions=True)

results = asyncio.run(main())

Pourquoi cette limite compte : les forfaits sont limités en requêtes simultanées, pas en requêtes par seconde. Les limites sont de 20 en paiement à l’usage, 25 en Starter, 100 en Pro, 200 en Business, 300 en Scale et 400 en Ultimate. Une requête au-delà de la limite reçoit immédiatement un 429 et n’est pas facturée. Le SDK relance un 429 tout seul avec un backoff, mais rester sous la limite garde votre exécution rapide et prévisible. Les détails sont dans limites de concurrence.

Gérer les Erreurs Comme un Pipeline, Pas Comme un Script

Un script lancé une seule fois peut planter sur une erreur. Une tâche qui tourne chaque nuit ne le devrait pas. Les SDK lèvent des erreurs typées, toutes sous-classes de ScrapeUnblockerError, et relancent déjà les erreurs transitoires (429, 502, 503, 504 et erreurs réseau) avec un backoff exponentiel. Un appel de plugin qui dépasse son temps renvoie désormais 502 et n’est pas facturé, donc la relance intégrée le couvre aussi.

Ce qu’il vous reste à gérer :

from scrapeunblocker import (
    Client,
    BudgetExceededError,
    ScrapeUnblockerError,
    ValidationError,
)

su = Client()

try:
    deals = su.bestbuy_search("oled tv", sort="discount", max_results=96)
except BudgetExceededError:
    # 402: this month's spend reached the limit you set. Stop, do not retry.
    raise SystemExit("Monthly budget reached, stopping the run")
except ValidationError as e:
    # 422: a parameter is missing or has the wrong type
    print("fix the request:", e.body)
except ScrapeUnblockerError as e:
    # anything that survived the built-in retries
    print("skipping this query:", e)

Le cas BudgetExceededError est nouveau. Vous pouvez maintenant fixer une limite de budget mensuel dans votre profil. Dès que vos dépenses de la période de facturation l’atteignent, les appels renvoient 402 jusqu’à la période suivante ou jusqu’à ce que vous releviez la limite. Pour les tâches planifiées, c’est un filet de sécurité simple : une boucle qui s’emballe ne vous réservera pas de mauvaise surprise sur la facture. Les SDK ne relancent jamais un 402, car il ne disparaît que lorsque l’état de facturation change.

La liste complète des codes de statut se trouve dans la référence des erreurs.

La Porte de Sortie plugin()

De nouveaux plugins arrivent régulièrement, et la version du SDK que vous avez installée n’a peut-être pas encore de méthode pour le plus récent. Pour ce cas, chaque client propose un appel générique qui prend le chemin de l’endpoint et ses paramètres :

data = su.plugin("/marketplace/target-search", query="tv", max_results=24)
const data = await su.plugin("/marketplace/target-search", { query: "tv", max_results: 24 });

Deux détails à retenir. Le chemin est celui qui figure en haut de la page de documentation de chaque plugin. Et les paramètres prennent les noms utilisés par l’API : en Node.js, vous écrivez donc ici max_results, et non le maxResults en camelCase qu’attendent les méthodes nommées.

Les Mêmes Plugins Dans Votre Assistant IA

Si vous utilisez Claude, ChatGPT ou un autre client MCP, vous n’avez pas besoin de code. Avec les nouveaux outils list_plugins et run_plugin, l’assistant trouve le bon plugin et le lance à partir d’une simple demande comme “Find coffee makers on Target under $50 and compare them with Walmart’s.” Lister les plugins est gratuit. Chaque exécution est facturée comme une requête API.

La configuration est décrite dans Give Claude Web Access With the ScrapeUnblocker MCP Server et dans la documentation MCP.

FAQ

Ai-je besoin d’un SDK pour utiliser les plugins ? Non. Chaque plugin est un endpoint HTTP classique : un POST avec les paramètres dans la query string et votre clé dans l’en-tête x-scrapeunblocker-key. Les SDK ajoutent des erreurs typées, des relances et des noms de méthodes, mais n’importe quel client HTTP fonctionne.

Comment les appels de plugins sont-ils facturés ? Une exécution de plugin puise dans le même quota de forfait que n’importe quelle autre requête API. Il n’y a pas de facturation séparée pour les plugins. Les appels rejetés avec 429, les dépassements de temps de plugin renvoyés en 502 et les blocages renvoyés en 403 ne sont pas facturés.

Pourquoi un champ manque-t-il sur certains produits ? Les plugins omettent les champs qui n’ont pas de valeur sur la page source. Un produit sans remise n’a pas de wasPrice, et une vignette de recherche sans marque n’a pas de brand. Lisez les champs avec une valeur par défaut, comme .get() en Python, au lieu de supposer qu’ils existent.

Puis-je tester un plugin avant d’écrire du code ? Oui. Ouvrez les plugins dans le tableau de bord, remplissez les champs et lancez-le. Vous obtenez le JSON et un extrait de code à copier dans votre projet.

Par Où Commencer

Choisissez un site dont vous collectez déjà les données à la main, trouvez son plugin dans la vue d’ensemble des plugins ou dans le catalogue de scrapers, et remplacez votre scraper par un seul appel de méthode. Ajoutez ensuite la limite de concurrence et la gestion des erreurs vues plus haut avant de le planifier.

ScrapeUnblocker gère les blocages, le rendu et le parsing derrière chaque plugin, si bien que votre code reste court quel que soit le site en face. Si vous n’avez pas encore de clé, vous pouvez commencer sur la page des tarifs.

Essayez ScrapeUnblocker gratuitement

Taux de réussite de plus de 95 % · à partir de 0,55 € pour 1 000 appels (TVA éventuelle en sus) · 500 requêtes gratuites à l'inscription.

Essayer gratuitement → Voir les tarifs