Office Depot est l'un des plus grands détaillants de fournitures de bureau aux États-Unis. L'entreprise exploite plus de 1 400 magasins, emploie plus de 38 000 personnes et possède les marques OfficeMax et Grand & Toy, en plus de son catalogue principal comprenant chaises, bureaux, papeterie, imprimantes et fournitures scolaires. Sa vitrine publique affiche les prix, les évaluations, le nombre d'avis et le statut de stock pour des milliers de références, ce qui en fait une source utile pour le suivi des prix concurrentiels, la recherche sur l'assortiment et la surveillance des inventaires.

Ce guide vous montre comment scraper Office Depot avec Python de façon fiable. Vous créez un petit script fonctionnel qui récupère une page produit rendue via la Crawling API, l'analyse avec BeautifulSoup, et extrait un enregistrement propre pour chaque article : nom du produit, prix, référence ou numéro de modèle, évaluation, nombre d'avis, disponibilité et URL du produit. L'ensemble du tutoriel se limite aux données du catalogue public, et la section sur la légalité vers la fin n'est pas un simple formulaire, donc lisez-la avant de pointer ce script sur un volume réel.

Ce que vous allez construire

Un script Python qui prend une URL de produit Office Depot, récupère la page rendue via la Crawling API, et extrait un enregistrement structuré. Nous utiliserons l'imprimante sans fil Epson Expression Home XP-4200 comme exemple et nous extrairons les champs suivants :

  • Nom du produit le titre de la fiche, par exemple "Epson Expression Home XP-4200 Wireless Color Inkjet All-In-One Printer".
  • Prix le prix affiché sur la page.
  • Référence / modèle le numéro d'article qui identifie le produit dans le catalogue Office Depot.
  • Évaluation la note moyenne en étoiles, lorsque le produit en possède une.
  • Nombre d'avis le nombre d'avis clients associés à cette note.
  • Disponibilité si l'article est indiqué en stock ou en rupture de stock.
  • URL du produit le lien canonique vers la page de détail du produit.

Pourquoi une simple requête échoue sur Office Depot

Si vous demandez une URL Office Depot avec un client HTTP basique, vous obtenez généralement une réponse avec le statut 200 mais presque aucune donnée produit dans le corps. Deux facteurs jouent contre vous. Premièrement, le site construit une grande partie de son contenu produits et prix côté client : le bloc de prix et plusieurs autres champs sont remplis par JavaScript après le chargement initial du HTML, de sorte qu'une récupération brute voit des espaces réservés à la place des valeurs. Deuxièmement, Office Depot détecte le trafic automatisé. Les adresses IP de datacenter et les comportements de requête qui ne ressemblent pas à un vrai navigateur sont confrontés à un CAPTCHA, limités en débit ou bloqués avant d'atteindre la page complète.

Un scraper Office Depot fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend réellement la page, et une adresse IP que la plateforme perçoit comme un vrai acheteur. Vous pouvez assembler cela vous-même avec un navigateur sans interface graphique plus un pool de proxys résidentiels rotatifs, mais maintenir cette infrastructure en bon état représente l'essentiel du travail. La Crawling API regroupe les deux en un seul appel : vous lui envoyez l'URL avec un token JavaScript, elle rend la page derrière une IP résidentielle fiable, et vous renvoie du HTML prêt à analyser. Pour plus d'informations sur la raison pour laquelle les pages rendues côté client résistent à une récupération simple, consultez comment crawler des sites JavaScript.

Pourquoi le token JS

Crawlbase propose deux types de tokens. Le token normal récupère du HTML statique ; le token JavaScript (JS) rend d'abord la page dans un vrai navigateur. Office Depot remplit son prix et plusieurs champs côté client, donc vous avez besoin du token JS ici. Le token normal renvoie la coque de pré-rendu, ce qui laisse les champs prix et stock vides lorsque BeautifulSoup les recherche.

Prérequis

Vous avez besoin de quelques éléments en place avant d'écrire du code. Aucun ne prend longtemps.

Python de base. Vous devez être à l'aise avec l'écriture et l'exécution d'un script Python et l'installation de paquets avec pip. Si vous êtes nouveau dans ce langage, notre guide sur le scraping web avec Python couvre les bases que ce tutoriel suppose acquises.

Python 3.8 ou ultérieur. Confirmez votre version avec python --version. Si vous ne l'avez pas, installez-le depuis python.org ou via une distribution comme Anaconda.

Un compte Crawlbase et un token JS. Inscrivez-vous, ouvrez votre tableau de bord, et copiez votre token JavaScript (JS) depuis la page de documentation du compte. Traitez le token comme un mot de passe : il authentifie vos requêtes, donc gardez-le hors du contrôle de version.

Configurer le projet

Créez un environnement virtuel pour isoler les dépendances du projet, puis installez les bibliothèques nécessaires au scraper.

bash
python --version

python -m venv office_depot_env
source office_depot_env/bin/activate

pip install crawlbase beautifulsoup4 pandas

Sous Windows, activez l'environnement avec office_depot_env\Scripts\activate à la place de la ligne source. Trois dépendances font le travail : crawlbase est le client officiel pour la Crawling API, beautifulsoup4 analyse le HTML retourné pour extraire chaque champ par sélecteur CSS, et pandas écrit les enregistrements en CSV à la fin.

Comprendre la page produit Office Depot

Une page produit Office Depot expose les mêmes quelques champs qui vous intéressent : un titre dans un en-tête, un prix dans un élément de prix dédié, un numéro d'article qui sert de référence, une note en étoiles avec un nombre d'avis, et un message de livraison qui vous indique si l'article est en stock. En dessous se trouvent une description et un tableau de spécifications.

Avant d'écrire des sélecteurs, ouvrez une page produit dans votre navigateur, faites un clic droit sur le titre et choisissez Inspecter. Office Depot préfixe la plupart de ses noms de classes avec od-, par exemple od-heading pour le titre et od-graphql-price-big-price pour le prix. Ce sont ces noms de classes que vous ciblez. Ils changent de temps en temps, donc traitez les sélecteurs ci-dessous comme un instantané actuel plutôt que comme un contrat permanent.

Étape 1 : Récupérer la page produit rendue

Commencez par obtenir la page complète. Importez la classe CrawlingAPI, initialisez-la avec votre token JS, et demandez l'URL du produit. Vérifier le code de statut avant d'analyser permet de rendre les échecs visibles plutôt que silencieux.

python
from crawlbase import CrawlingAPI

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"})

def crawl(page_url):
    options = {"ajax_wait": "true", "page_wait": 5000}
    response = api.get(page_url, options)
    if response["status_code"] == 200:
        return response["body"].decode("utf-8")
    print(f"Request failed: {response['status_code']}")
    return None

if __name__ == "__main__":
    url = "https://www.officedepot.com/a/products/8761287/Epson-Expression-Home-XP-4200-Wireless/"
    html = crawl(url)
    print(html[:500] if html else "No HTML returned")

Les deux options d'attente sont importantes pour une cible rendue côté client comme celle-ci. ajax_wait demande à l'API d'attendre que le contenu asynchrone ait fini de se charger, et page_wait attend un nombre fixe de millisecondes après le chargement pour que les champs prix et stock à rendu tardif apparaissent avant la capture de la page. Cinq secondes est un bon point de départ ; augmentez-les si des champs reviennent vides. Exécutez le script et vous devriez voir du vrai balisage produit, pas la coque de pré-rendu qu'une récupération simple renverrait. Cela confirme que le rendu fonctionne avant que vous n'écriviez un seul sélecteur.

Crawlbase Crawling API

Office Depot nécessite une page rendue derrière une IP fiable, en un seul appel, pour que les champs prix et stock soient réellement présents lors de l'analyse. La Crawling API prend un token JS, exécute la page dans un vrai navigateur, fait tourner les IP résidentielles côté serveur, et vous remet du HTML prêt à analyser, vous évitant d'exploiter vous-même une flotte sans interface graphique et un pool de proxys. Pointez-la sur une seule URL produit sur le niveau gratuit d'abord.

Étape 2 : Analyser les champs avec BeautifulSoup

Avec le HTML rendu en main, chargez-le dans BeautifulSoup et extrayez chaque champ par son sélecteur. Office Depot expose le titre dans h1.od-heading.sku-heading, le prix dans span.od-graphql-price-big-price, et le message de livraison dans span.od-delivery-message-text. Un petit utilitaire qui retourne une valeur par défaut quand un élément est absent empêche l'extraction de planter sur un champ manquant dans une page donnée.

python
from bs4 import BeautifulSoup

def text_of(soup, selector, default="N/A"):
    el = soup.select_one(selector)
    return el.get_text(strip=True) if el else default

def parse_rating(soup):
    el = soup.select_one(".od-stars-inner")
    if not el or not el.get("style"):
        return None
    # style is like "width: 86%"; map percent of 5 stars
    percent = el["style"].split(":")[-1].strip().rstrip("%")
    try:
        return round(float(percent) / 20, 1)
    except ValueError:
        return None

def extract_product(html, url):
    soup = BeautifulSoup(html, "html.parser")
    reviews = text_of(soup, ".od-reviews-count-number").strip("()")
    sku = text_of(soup, ".od-product-card-region-product-number").split("#")[-1]
    delivery = text_of(soup, "span.od-delivery-message-text", "").lower()
    availability = "In Stock" if "in stock" in delivery else "Out of Stock"
    return {
        "name": text_of(soup, "h1.od-heading.sku-heading"),
        "price": text_of(soup, "span.od-graphql-price-big-price"),
        "sku": sku,
        "rating": parse_rating(soup),
        "review_count": reviews,
        "availability": availability,
        "product_url": url,
    }

L'utilitaire text_of retourne une valeur par défaut quand un élément est absent au lieu de planter sur un appel .get_text() contre rien. La référence provient de .od-product-card-region-product-number, divisée sur le # pour ne garder que le numéro d'article. Office Depot encode la note en étoiles sous forme de pourcentage de largeur CSS sur .od-stars-inner, donc parse_rating lit ce pourcentage et le divise par 20 pour récupérer une valeur sur cinq. Le nombre d'avis se trouve dans .od-reviews-count-number enveloppé de parenthèses, que strip("()") supprime, et la disponibilité est dérivée du texte du message de livraison. Pour un rappel sur la sélection des éléments, consultez comment utiliser BeautifulSoup en Python.

Un point à anticiper : les noms de classes od- d'Office Depot (l'élément de prix od-graphql-price-big-price, la barre de notation od-stars-inner) changent sans préavis, et la mise en page évolue aussi occasionnellement. Traitez les sélecteurs ci-dessus comme un modèle de départ, pas comme un contrat. Quand un champ revient comme N/A ou None sur une page que vous savez avoir cette valeur, réinspectez la page en direct dans les outils de développement de votre navigateur et mettez à jour le sélecteur. La maintenance périodique des sélecteurs est normale pour tout scraper en production, pas le signe que quelque chose est cassé.

Étape 3 : Assembler le tout

Reliez maintenant la récupération, l'analyse et l'écriture CSV en un seul script exécutable. Récupérez la page rendue, transmettez-la à l'extracteur, affichez l'enregistrement et sauvegardez-le avec pandas.

python
import json
import pandas as pd
from crawlbase import CrawlingAPI
from bs4 import BeautifulSoup

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"})

def crawl(page_url):
    options = {"ajax_wait": "true", "page_wait": 5000}
    response = api.get(page_url, options)
    if response["status_code"] == 200:
        return response["body"].decode("utf-8")
    print(f"Request failed: {response['status_code']}")
    return None

def text_of(soup, selector, default="N/A"):
    el = soup.select_one(selector)
    return el.get_text(strip=True) if el else default

def parse_rating(soup):
    el = soup.select_one(".od-stars-inner")
    if not el or not el.get("style"):
        return None
    percent = el["style"].split(":")[-1].strip().rstrip("%")
    try:
        return round(float(percent) / 20, 1)
    except ValueError:
        return None

def extract_product(html, url):
    soup = BeautifulSoup(html, "html.parser")
    reviews = text_of(soup, ".od-reviews-count-number").strip("()")
    sku = text_of(soup, ".od-product-card-region-product-number").split("#")[-1]
    delivery = text_of(soup, "span.od-delivery-message-text", "").lower()
    availability = "In Stock" if "in stock" in delivery else "Out of Stock"
    return {
        "name": text_of(soup, "h1.od-heading.sku-heading"),
        "price": text_of(soup, "span.od-graphql-price-big-price"),
        "sku": sku,
        "rating": parse_rating(soup),
        "review_count": reviews,
        "availability": availability,
        "product_url": url,
    }

def main():
    url = "https://www.officedepot.com/a/products/8761287/Epson-Expression-Home-XP-4200-Wireless/"
    html = crawl(url)
    if not html:
        return
    product = extract_product(html, url)
    print(json.dumps(product, indent=2))
    pd.DataFrame([product]).to_csv("office_depot_products.csv", index=False)
    print("Saved to office_depot_products.csv")

if __name__ == "__main__":
    main()

À quoi ressemble le résultat

Exécutez le script complet avec python scraper.py et vous obtenez un enregistrement propre, prêt à écrire en JSON, CSV ou dans une base de données. L'affichage JSON ressemble à ceci :

json
{
  "name": "Epson Expression Home XP-4200 Wireless Color Inkjet All-In-One Printer",
  "price": "$99.99",
  "sku": "8761287",
  "rating": 4.3,
  "review_count": "512",
  "availability": "In Stock",
  "product_url": "https://www.officedepot.com/a/products/8761287/Epson-Expression-Home-XP-4200-Wireless/"
}

Mise à l'échelle vers une page de recherche et la pagination

Un seul produit est une démonstration ; un vrai travail en collecte beaucoup. Les résultats de recherche d'Office Depot présentent une grille de fiches produits, chacune portant un titre, un prix, une note, un nombre d'avis, un numéro d'article et un lien vers la page produit. Vous scrappez cette grille de la même façon : sélectionnez chaque fiche, extrayez les mêmes champs par fiche, puis suivez les liens vers les pages produits quand vous avez besoin du détail approfondi. La recherche pagine avec un paramètre &page=, donc vous parcourez les pages en l'incrémentant et en vous arrêtant quand une page ne retourne aucune fiche.

python
import time

def extract_cards(html):
    soup = BeautifulSoup(html, "html.parser")
    grid = ".od-search-browse-products-vertical-grid-product"
    products = []
    for card in soup.select(grid):
        link_el = card.select_one(".od-product-card-region-description a")
        href = link_el["href"] if link_el else ""
        products.append({
            "name": text_of(card, ".od-product-card-region-description a"),
            "price": text_of(card, ".od-graphql-price-big-price"),
            "review_count": text_of(card, ".od-reviews-count-number").strip("()"),
            "product_url": "https://www.officedepot.com" + href if href else "N/A",
        })
    return products

def scrape_all_pages(base_url, max_pages=5):
    all_products = []
    for page in range(1, max_pages + 1):
        html = crawl(f"{base_url}&page={page}")
        if not html:
            break
        products = extract_cards(html)
        if not products:
            break
        all_products.extend(products)
        print(f"Page {page}: {len(products)} products")
        time.sleep(2)
    return all_products

Le plafond max_pages limite une exécution pour qu'une requête large ne tourne pas indéfiniment, et la rupture sur les résultats vides vous arrête tôt quand la recherche n'a plus de pages. Le time.sleep(2) entre les pages régule les requêtes pour que vous ne marteliez pas la recherche en boucle serrée, ce qui est le moyen le plus rapide d'être limité en débit. Pour plus d'informations sur la structuration des crawls multi-pages de commerce en ligne, notre guide sur le scraping web e-commerce couvre les modèles en profondeur.

Vous préférez une sortie structurée ?

Si vous préférez ne pas maintenir du tout les sélecteurs CSS, la Crawling API avec auto-analyse retourne du JSON structuré prêt à l'emploi pour les pages e-commerce courantes, vous donnant des champs comme le nom, le prix et la note sans écrire de code d'extraction. C'est une bonne option quand vous voulez que la forme des données soit gérée pour vous et que la dérive des sélecteurs soit traitée en amont.

Rester non bloqué

Même avec le rendu pris en charge, Office Depot surveille le trafic à l'allure d'un scraper. Quelques bonnes habitudes maintiennent une exécution en bonne santé, et elles s'appliquent à toute cible commerciale difficile.

  • Cadencez vos requêtes. Étalez les requêtes avec un délai entre les pages et variez vos recherches au lieu de crawler un seul terme à pleine vitesse. Le time.sleep dans la boucle de pagination est un plancher, pas un plafond.
  • Appuyez-vous sur la rotation. Un pool d'IP résidentielles répartit les requêtes sur de nombreuses adresses d'utilisateurs réels pour qu'aucune ne déclenche une limite de débit. La Crawling API gère cela pour vous ; si vous construisez votre propre infrastructure, c'est la partie à bien soigner.
  • Lisez les codes de statut. Une exécution qui commence à renvoyer des défis ou des erreurs vous indique que le débit ou le niveau d'IP actuel n'est plus suffisant. Traitez cela comme un signal pour ralentir, pas comme du bruit à ignorer.

Pour le guide complet, consultez comment scraper des sites web sans être bloqué. Si vous préférez acheminer votre propre trafic via un pool rotatif plutôt que d'utiliser l'API gérée, le Smart AI Proxy (également appelé AI Proxy) vous donne la même rotation d'IP résidentielles sous forme de point de terminaison proxy.

Est-il légal de scraper Office Depot ?

Le fait que le scraping d'Office Depot soit autorisé dépend des conditions d'utilisation d'Office Depot, de votre juridiction et de ce que vous faites avec les données. Les conditions d'Office Depot restreignent l'accès automatisé, donc le scraping peut aller à l'encontre de ces conditions quel que soit le soin apporté à vos outils. Aucun code ici ne change cela ; il rend simplement la partie technique fonctionnelle. Lisez les conditions d'utilisation d'Office Depot et son robots.txt, et traitez les deux comme la limite de ce que vous collectez.

Quelques lignes à respecter. Collectez uniquement les données du catalogue public : les noms de produits, les prix, les références, les notes, les nombres d'avis, la disponibilité et les liens de fiches que n'importe qui peut voir sans compte. Maintenez votre volume de requêtes suffisamment bas pour ne pas solliciter excessivement les serveurs d'Office Depot. Évitez les données personnelles, y compris tout ce qui est lié à des acheteurs, des évaluateurs ou des employés identifiables, et ne redistribuez pas de photographies ou de descriptions de produits protégées par des droits d'auteur comme si elles vous appartenaient. Le scraping à des fins de recherche interne ou de comparaison de prix est bien plus défendable que le scraping pour republier ou revendre le catalogue en masse.

Ce guide est délibérément limité aux pages de catalogue et de recherche publics car c'est la ligne qui rend le travail défendable. Il ne couvre rien derrière une connexion, les données de compte ou de commande, les flux de paiement ou de paiement, ni aucune tentative de contournement de l'authentification. Pour un accès licencié ou à fort volume, la bonne voie est un flux officiel, une API ou un accord de données avec Office Depot plutôt qu'un scraper plus sophistiqué. Si votre projet nécessite une structure garantie, de gros volumes ou des droits commerciaux, demandez d'abord un accès sanctionné ; un outil de crawling géré ne gère que la récupération, pas la permission d'utiliser les données.

Récapitulatif

Points clés

  • Office Depot remplit les champs clés côté client. Une récupération simple renvoie une coque de pré-rendu avec le prix et le stock vides, donc vous devez rendre la page avant de l'analyser.
  • Vous avez besoin du rendu et d'une IP fiable ensemble. La Crawling API avec un token JS fait les deux en un seul appel ; ajax_wait et page_wait contrôlent combien de temps elle attend les champs tardifs.
  • BeautifulSoup effectue l'extraction. Mappez le nom, le prix, la référence, la note, le nombre d'avis, la disponibilité et l'URL du produit aux sélecteurs od- actuels, et anticipez la dérive de ces sélecteurs.
  • Mettez à l'échelle avec la recherche et la pagination. Bouclez sur la grille de fiches de résultats, parcourez &page= jusqu'à ce qu'une page ne renvoie aucune fiche, cadencez les requêtes avec un délai, et plafonnez le nombre de pages.
  • Restez sur les données publiques. Respectez les CGU et le robots.txt d'Office Depot, préférez un flux ou une API officielle pour les données licenciées ou en masse, et ne touchez jamais aux comptes, commandes ou informations personnelles.

Foire aux questions

Pourquoi une requête simple ne renvoie-t-elle aucun prix d'Office Depot ?

Parce qu'Office Depot remplit son prix et plusieurs autres champs côté client avec JavaScript. Le HTML initial est une coque de pré-rendu, donc une requête HTTP brute renvoie un statut 200 avec les champs prix et stock vides. Pour obtenir de vraies valeurs, vous devez d'abord rendre la page, ce que le token JS de la Crawling API gère pour vous.

Ai-je besoin du token normal ou du token JS pour Office Depot ?

Le token JS. Le token normal récupère le HTML statique, ce qui laisse les champs prix et disponibilité non remplis sur Office Depot. Le token JS rend la page dans un vrai navigateur avant de renvoyer le HTML, de sorte que ces champs sont présents lorsque BeautifulSoup les analyse.

Quels champs puis-je extraire d'une page produit Office Depot ?

Les champs publics affichés sur la page : le nom du produit, le prix, le numéro d'article servant de référence ou de modèle, la note en étoiles, le nombre d'avis, la disponibilité et l'URL canonique du produit. Les fiches de résultats de recherche exposent la plupart des mêmes champs par fiche, ce qui vous permet de collecter de nombreux produits avant d'explorer des pages individuelles.

Comment scraper toutes les pages d'une recherche Office Depot ?

La recherche pagine avec un paramètre &page= sur l'URL. Incrémentez-le dans une boucle, scrapez chaque page avec le même parseur de fiches, et arrêtez-vous quand une page ne renvoie aucun produit. Plafonnez le nombre de pages et ajoutez un court délai entre les requêtes pour cadencer l'exécution et éviter d'être limité en débit.

Mes sélecteurs retournent N/A. Qu'est-ce qui a changé ?

Presque certainement le balisage d'Office Depot. Ses noms de classes od- comme od-graphql-price-big-price pour le prix et od-stars-inner pour la barre de notation changent sans préavis, et la mise en page évolue aussi occasionnellement. Réinspectez une page en direct dans les outils de développement de votre navigateur et mettez à jour les sélecteurs. La maintenance périodique est normale pour tout scraper en production.

Puis-je scraper les données de compte ou de commande d'Office Depot ?

Non, et ce guide ne le couvre pas. Les détails de compte, l'historique des commandes et les flux de paiement se trouvent derrière une connexion, ce ne sont donc pas des données publiques. Le scraping de contenu protégé par connexion, ou le contournement de l'authentification pour l'atteindre, est hors de portée ici et va à l'encontre des conditions d'Office Depot. Pour un accès sanctionné à des données plus riches, la bonne voie est un flux officiel, une API ou un accord de données.

Commencer à construire

Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.

Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.

En libre-service · Sans appel commercial requis · Volumes de crawl entreprise disponibles