Shein est l'un des plus grands détaillants de mode éphémère sur le web, avec un catalogue tentaculaire de vêtements pour hommes et femmes, d'accessoires et d'articles pour la maison qui se renouvelle en permanence. Chaque page de catégorie et de recherche est une grille publique de produits : un titre, un prix, une note en étoiles et un lien vers la page propre du produit, tous visibles par n'importe quel visiteur sans compte. Ces données d'annonce publiques, voilà ce que les dropshippers, les trackers de prix et les chercheurs en marketing surveillent pour repérer les bonnes affaires, suivre les prix et identifier les tendances.

Ce guide vous montre comment scraper les annonces Shein avec Python. Vous construisez un petit script fonctionnel qui récupère une page de catégorie ou de recherche Shein via la Crawling API, analyse un enregistrement propre pour chaque produit, gère la pagination et exporte les résultats en JSON et CSV. L'ensemble du tutoriel reste limité aux données d'annonce publiques : les noms de produits, les prix, les notes et les liens que tout le monde peut voir sur une page d'annonce Shein sans se connecter.

Ce que vous allez construire

Un script Python qui prend une URL de catégorie ou de recherche Shein, récupère la page rendue via la Crawling API et extrait un enregistrement structuré par produit dans la grille. Nous utilisons une page de catégorie de vêtements pour femmes comme exemple fil conducteur. Pour chaque fiche produit, le scraper extrait ces champs :

  • Title le nom du produit affiché sur la fiche d'annonce.
  • Price le prix de vente actuel, lorsque la fiche en affiche un.
  • Rating la note en étoiles moyenne affichée sur la fiche.
  • Link l'URL absolue vers la page de détail du produit.
  • Image l'URL de l'image du produit issue de la vignette de la fiche.

Ces champs correspondent directement à ceux que l'ancien tutoriel collectait (nom du produit, prix, notes et URLs d'images), réduits à ce qu'une grille d'annonces expose réellement. Les détails par produit tels que le SKU, la description complète, les couleurs et les tailles se trouvent sur la page de détail propre à chaque produit, que vous atteignez en suivant le champ link et en analysant cette page de la même manière.

Pourquoi une requête simple échoue sur Shein

Si vous pointez un client HTTP nu vers une URL de catégorie Shein, vous obtenez rarement la grille de produits souhaitée. Deux facteurs jouent contre vous. Premièrement, Shein rend ses annonces côté client : le serveur envoie une coquille légère et remplit les fiches produits à mesure que le JavaScript de la page s'exécute et que vous faites défiler la page, de sorte que le HTML initial est généralement dépourvu de la plupart des produits. Une bibliothèque qui ne lit que la première réponse HTTP, sans navigateur pour exécuter les scripts, voit une page presque vide.

Deuxièmement, Shein signale le trafic automatisé. Les plages d'adresses IP de centres de données et les modèles de requêtes qui ne ressemblent pas à un vrai acheteur se heurtent à une page de défi, une redirection régionale ou un blocage pur avant même d'atteindre la grille. Un scraper Shein fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend la page et une adresse IP que Shein perçoit comme un vrai visiteur. Vous pouvez assembler cela vous-même avec un navigateur sans interface graphique et un pool de proxies résidentiels rotatifs, mais maintenir cette pile en bonne santé représente l'essentiel du travail. La Crawling API regroupe les deux en un seul appel : vous lui envoyez l'URL de l'annonce, elle rend la page derrière une adresse IP résidentielle de confiance, gère la rotation et tout défi éventuel, et vous retourne le HTML finalisé à analyser.

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 pour écrire et exécuter un script Python et installer des paquets avec pip. Si vous êtes novice dans ce langage, la documentation officielle Python ou n'importe quel cours pour débutants couvre le niveau que ce tutoriel suppose, et notre guide sur l'utilisation de BeautifulSoup en Python présente en profondeur la bibliothèque d'analyse.

Python 3.8 ou version ultérieure. Vérifiez votre version avec python --version (ou python3 --version). Si vous ne l'avez pas, installez-le depuis python.org et assurez-vous que Python est dans le PATH de votre système.

Un compte Crawlbase et un token. Inscrivez-vous pour un compte gratuit, ouvrez votre tableau de bord et copiez votre token depuis la page de documentation du compte. Le niveau gratuit inclut jusqu'à 20 000 requêtes sans carte, ce qui est largement suffisant pour construire et tester ce scraper. Shein nécessite le token JavaScript car l'annonce est rendue côté client. Traitez le token comme un mot de passe et ne le mettez pas dans le contrôle de version.

Configurer le projet

Créez un environnement virtuel pour que les dépendances du projet restent isolées, puis installez les deux bibliothèques dont le scraper a besoin. crawlbase est le client officiel pour la Crawling API, et beautifulsoup4 analyse le HTML retourné afin que vous puissiez extraire chaque champ des fiches produits par sélecteur CSS.

bash
python --version

python -m venv shein_env
source shein_env/bin/activate

pip install crawlbase beautifulsoup4

Sous Windows, activez l'environnement avec shein_env\Scripts\activate à la place de la ligne source. Une fois les deux bibliothèques installées, créez le fichier de script que la suite du guide développe :

bash
touch shein_listing.py

Comprendre la page d'annonce

Une annonce Shein se trouve à une URL de catégorie telle que https://www.shein.com/Women-Clothing-c-2030.html, ou à une URL de recherche telle que https://www.shein.com/pdsearch/dress/. Les deux affichent une grille de fiches produits, une par produit, chacune portant le même ensemble de champs : une image miniature, un titre, un prix, une note en étoiles facultative et un lien vers la page de détail du produit.

Avant d'écrire des sélecteurs, ouvrez une page d'annonce dans votre navigateur, faites un clic droit sur une fiche produit et choisissez Inspecter. Shein enveloppe chaque produit dans une section marquée d'une class contenant product-card, place le titre dans un élément de lien ou de nom, affiche le prix dans un élément de prix dédié et expose la vignette et le lien produit à l'intérieur de ce conteneur. Ce sont les éléments que vous ciblez. Les noms de classes exacts de Shein évoluent au fil du temps, donc dans la mesure du possible, appuyez-vous sur des correspondances partielles comme une sous-chaîne product-card plutôt que sur une chaîne complète de classes fragile.

Étape 1 : Récupérer la page d'annonce rendue

Commencez par obtenir la page finalisée. Importez la classe CrawlingAPI, initialisez-la avec votre token, définissez l'URL de l'annonce et demandez-la avec le rendu activé. Vérifier le code de statut avant d'analyser permet de détecter les échecs de manière explicite plutôt que silencieuse.

python
from crawlbase import CrawlingAPI

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_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", "ignore")
    print(f"Request failed: {response['status_code']}")
    return None

if __name__ == "__main__":
    listing_url = "https://www.shein.com/Women-Clothing-c-2030.html"
    html = crawl(listing_url)
    print(html[:500] if html else "No HTML returned")

Les deux options d'attente sont importantes pour une grille qui se remplit au chargement de la page. ajax_wait indique à l'API d'attendre que le contenu asynchrone soit terminé, et page_wait maintient la pause pendant un nombre fixe de millisecondes après le chargement afin que les fiches rendues tardivement apparaissent avant la capture de la page. Exécutez le script et vous devriez voir du vrai balisage de produit, pas une coquille presque vide. Cela confirme que le rendu fonctionne avant d'écrire un seul sélecteur.

Crawlbase Crawling API

Cette grille de produits n'apparaît qu'une fois que le JavaScript de la page s'exécute, et seulement si Shein perçoit la requête comme provenant d'un vrai acheteur. La Crawling API prend votre token, exécute la page d'annonce dans un vrai navigateur, fait tourner les adresses IP résidentielles côté serveur et gère tout défi éventuel, puis vous remet le HTML finalisé. Vous n'avez pas besoin de gérer vous-même une flotte de navigateurs sans interface graphique ni un pool de proxies. Pointez-la d'abord vers une catégorie ou une URL de recherche sur le niveau gratuit de 20 000 requêtes.

Étape 2 : Analyser les fiches produits avec BeautifulSoup

HTML rendu en main, chargez-le dans BeautifulSoup, trouvez chaque fiche produit et extrayez chaque champ par son sélecteur. Shein enveloppe chaque produit dans un conteneur de fiche sur lequel vous sélectionnez, place le titre dans un lien de nom, affiche le prix dans un élément de prix et expose l'image miniature et le lien produit à l'intérieur de la fiche. Enveloppez chaque fiche dans un try/except afin qu'une annonce malformée ne plante pas l'exécution.

python
from bs4 import BeautifulSoup

BASE = "https://www.shein.com"

def text_of(card, selector):
    el = card.select_one(selector)
    return el.get_text(strip=True) if el else None

def absolute(href):
    if not href:
        return None
    if href.startswith("//"):
        return "https:" + href
    return href if href.startswith("http") else BASE + href

def parse_link(card):
    a = card.select_one("a[href]")
    return absolute(a["href"]) if a else None

def parse_image(card):
    img = card.select_one("img")
    if not img:
        return None
    src = img.get("src") or img.get("data-src")
    return absolute(src)

def scrape_listing(html):
    soup = BeautifulSoup(html, "html.parser")
    cards = soup.select("section[class*='product-card']")
    results = []
    for card in cards:
        try:
            title = text_of(card, "a.goods-title-link")
            if not title:
                continue
            results.append({
                "title": title,
                "price": text_of(card, "span.product-card__price"),
                "rating": text_of(card, "span.rate-num"),
                "link": parse_link(card),
                "image": parse_image(card),
            })
        except Exception as e:
            print(f"Skipped a card: {e}")
    return results

L'aide text_of interroge un élément à l'intérieur d'une fiche et retourne None lorsqu'il est absent, au lieu de lever une exception sur un appel .get_text() contre rien. Cela rend l'extraction robuste quand un champ est absent, ce qui est courant puisque chaque produit n'affiche pas forcément une note. L'aide absolute normalise les liens et les sources d'images en URLs complètes, car Shein sert souvent une source relative au protocole // ou un href relatif. Ignorer toute fiche sans titre élimine les emplacements vides que Shein laisse dans la grille.

Selectors drift

Les noms de classes de Shein (le conteneur de fiche, le span de prix, l'élément de note) évoluent à mesure que le site se met à jour, tandis que les modèles structurels comme une sous-chaîne product-card et une ancre interne sont plus durables. Traitez les sélecteurs à base de classes ci-dessus comme un modèle de départ, pas comme un contrat. Lorsqu'un champ retourne None pour chaque fiche, ré-inspectez la page d'annonce en direct dans les outils de développement de votre navigateur et mettez le sélecteur à jour. La maintenance périodique des sélecteurs est normale pour tout scraper en production.

Étape 3 : Assembler le script et exporter en JSON et CSV

Câblez maintenant la récupération et l'analyse dans un script exécutable, puis écrivez les enregistrements en JSON et CSV afin de pouvoir les charger dans un notebook ou une feuille de calcul. Récupérez la page d'annonce rendue, passez-la à l'analyseur et exportez les lignes structurées.

python
import csv
import json
from crawlbase import CrawlingAPI
from bs4 import BeautifulSoup

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"})
BASE = "https://www.shein.com"
FIELDS = ["title", "price", "rating", "link", "image"]

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", "ignore")
    print(f"Request failed: {response['status_code']}")
    return None

def text_of(card, selector):
    el = card.select_one(selector)
    return el.get_text(strip=True) if el else None

def absolute(href):
    if not href:
        return None
    if href.startswith("//"):
        return "https:" + href
    return href if href.startswith("http") else BASE + href

def parse_link(card):
    a = card.select_one("a[href]")
    return absolute(a["href"]) if a else None

def parse_image(card):
    img = card.select_one("img")
    if not img:
        return None
    src = img.get("src") or img.get("data-src")
    return absolute(src)

def scrape_listing(html):
    soup = BeautifulSoup(html, "html.parser")
    cards = soup.select("section[class*='product-card']")
    results = []
    for card in cards:
        try:
            title = text_of(card, "a.goods-title-link")
            if not title:
                continue
            results.append({
                "title": title,
                "price": text_of(card, "span.product-card__price"),
                "rating": text_of(card, "span.rate-num"),
                "link": parse_link(card),
                "image": parse_image(card),
            })
        except Exception as e:
            print(f"Skipped a card: {e}")
    return results

def export(rows, name="shein_listing"):
    with open(f"{name}.json", "w", encoding="utf-8") as f:
        json.dump(rows, f, indent=2, ensure_ascii=False)
    with open(f"{name}.csv", "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=FIELDS)
        writer.writeheader()
        writer.writerows(rows)
    print(f"Saved {len(rows)} products to {name}.json and {name}.csv")

def main():
    url = "https://www.shein.com/Women-Clothing-c-2030.html"
    html = crawl(url)
    if not html:
        return
    rows = scrape_listing(html)
    export(rows)

if __name__ == "__main__":
    main()

Exécutez le script complet avec python shein_listing.py. Il récupère la page d'annonce rendue, analyse une ligne par produit et écrit shein_listing.json et shein_listing.csv. La liste FIELDS partagée maintient l'ordre des colonnes CSV en accord avec les clés du dictionnaire, de sorte que les deux exports ne divergent jamais.

À quoi ressemble le résultat

Vous obtenez une liste propre d'enregistrements de produits, dans l'ordre de la grille, prête à être écrite en JSON, CSV ou dans une base de données.

json
[
  {
    "title": "Women's Ribbed Knit Long Sleeve Bodycon Dress",
    "price": "$12.49",
    "rating": "4.92",
    "link": "https://www.shein.com/Ribbed-Knit-Bodycon-Dress-p-12345678.html",
    "image": "https://img.ltwebstatic.com/images/ribbed-dress.jpg"
  },
  {
    "title": "Floral Print Tie Front Blouse",
    "price": "$9.00",
    "rating": "4.78",
    "link": "https://www.shein.com/Floral-Print-Blouse-p-87654321.html",
    "image": "https://img.ltwebstatic.com/images/floral-blouse.jpg"
  }
]

Passer à l'échelle sur plusieurs pages et catégories

Une page est une démonstration ; un vrai travail de recherche s'étend à toute la catégorie. Shein pagine ses annonces avec un paramètre de requête ?page=, donc vous parcourez les pages dans l'ordre jusqu'à ce qu'une page revienne vide, puis vous passez à la catégorie suivante. Espacez les requêtes pour ne pas marteler Shein dans une boucle serrée.

python
import time

CATEGORIES = {
    "women-clothing": "https://www.shein.com/Women-Clothing-c-2030.html",
    "dresses": "https://www.shein.com/Dresses-c-1727.html",
}

def scrape_categories(categories, max_pages=5):
    everything = {}
    for name, base_url in categories.items():
        rows = []
        for page in range(1, max_pages + 1):
            sep = "&" if "?" in base_url else "?"
            page_url = f"{base_url}{sep}page={page}"
            html = crawl(page_url)
            if not html:
                break
            found = scrape_listing(html)
            if not found:
                break
            rows.extend(found)
            print(f"{name} page {page}: {len(found)} products")
            time.sleep(2)
        everything[name] = rows
    return everything

L'interruption sur résultat vide vous arrête tôt quand une catégorie est épuisée, le plafond max_pages maintient une exécution bornée, et le time.sleep(2) entre les requêtes rythme l'exécution pour éviter d'être signalé pour du trafic en rafale. Classer la sortie par nom de catégorie garde chaque liste séparée, ce qui est utile pour comparer les prix entre catégories. Pour suivre les évolutions de prix dans le temps, exécutez le job selon un planning, horodatez chaque export et comparez les instantanés successifs. Cela s'intègre directement dans un flux de travail d'intelligence tarifaire, où les champs d'annonce que vous collectez ici deviennent le signal brut.

Rester non bloqué

Même avec le rendu pris en charge, Shein surveille le trafic aux allures de scraper. Quelques habitudes maintiennent une exécution saine et s'appliquent à n'importe quelle cible commerciale difficile.

  • Espacez vos requêtes. Répartissez les requêtes avec un délai entre les pages et les catégories plutôt que de tout parcourir à pleine vitesse. Planifiez les jobs plus lourds pendant les heures creuses pour alléger la charge sur les serveurs de Shein.
  • Misez sur la rotation. Un pool d'adresses IP résidentielles répartit les requêtes sur de nombreuses adresses d'utilisateurs réels de sorte qu'aucune ne déclenche une limite de débit. La Crawling API gère cela pour vous ; si vous montez votre propre pile, c'est la partie à soigner.
  • Ne conservez que ce dont vous avez besoin. Stockez les champs d'annonce que votre projet utilise et éliminez le reste. Vérifiez périodiquement vos sélecteurs pour que le scraper suive les modifications du balisage.

Pour le guide plus large sur l'évitement des blocages, voir comment scraper des sites web sans être bloqué, et pour plus d'informations sur l'importance du rendu ici, comment crawler des sites web JavaScript. Pour le contexte plus large de l'extraction de données produits structurées depuis des boutiques en ligne, notre présentation du scraping e-commerce couvre les modèles que ce scraper suit.

Est-il légal de scraper Shein ?

La légalité du scraping de Shein dépend des conditions d'utilisation de Shein, de votre juridiction et de ce que vous faites des données. Les conditions de Shein restreignent l'accès automatisé, de sorte que le scraping peut aller à l'encontre de ces conditions quelle que soit la précaution de vos outils. Aucun code présenté ici ne change cela ; il ne fait que rendre la partie technique fonctionnelle. Lisez les conditions d'utilisation de Shein et son fichier robots.txt, et traitez les deux comme la frontière de ce que vous collectez. Pour un usage commercial ou concurrentiel, le tableau juridique se complexifie, et consulter un expert juridique pour votre cas spécifique est la démarche sensée.

Quelques lignes à respecter. Collectez uniquement les données publiques : les titres de produits, les prix, les notes, les liens d'annonce et les images miniatures que tout le monde peut voir sur une page d'annonce Shein sans compte. Maintenez un volume de requêtes suffisamment faible pour ne pas solliciter les serveurs de Shein, et évitez les données personnelles, notamment tout ce qui est lié à des acheteurs ou des évaluateurs identifiables au-delà de ce qui est publiquement listé. Ne redistribuez pas la photographie de produit de Shein comme si elle vous appartenait ; une URL d'image est une référence, pas une licence pour republier le média. Si vous envisagez de réutiliser les données commercialement, obtenez une autorisation ou un accord officiel plutôt que de supposer que le silence vaut consentement.

Ce guide est délibérément limité aux pages publiques de catégories et de recherche d'annonces parce que 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 informations personnelles, ni aucune tentative de contournement d'une authentification ou d'un défi auquel vous n'êtes pas en droit de répondre. Si Shein propose un programme d'affiliation ou de partenariat adapté à votre cas d'utilisation, c'est le bon outil lorsque vous avez besoin de grands volumes, d'une structure garantie ou de droits commerciaux. Si votre projet nécessite plus que des données d'annonces publiques, la voie officielle ou un accord de données est la bonne approche, pas un scraper plus astucieux.

Récapitulatif

Points clés

  • Les annonces sont un signal produit public. Chaque page de catégorie et de recherche Shein présente des titres, des prix, des notes et des liens, ce qui la rend si utile pour le suivi des prix et la recherche produit.
  • Vous avez besoin du rendu et d'une adresse IP de confiance ensemble. Shein remplit la grille de produits côté client et bloque le trafic de bots, donc la Crawling API rend la page derrière une adresse IP résidentielle en un seul appel.
  • BeautifulSoup effectue l'extraction. Parcourez les conteneurs product-card et mappez title, price, rating, link et image sur les sélecteurs actuels, en sachant que ces sélecteurs évolueront.
  • Exportez en JSON et CSV. Une liste de champs partagée maintient les deux fichiers synchronisés, et la pagination avec ?page= jusqu'à ce qu'une page soit vide étend l'exécution à toute une catégorie.
  • Restez sur les données publiques. Respectez les conditions d'utilisation et le robots.txt de Shein, ne republiez pas les images de produits et ne touchez jamais aux comptes, aux commandes ni aux informations personnelles.

Foire aux questions

Pourquoi une requête simple ne retourne-t-elle aucun produit de Shein ?

Shein rend ses annonces côté client, donc une requête HTTP brute obtient une coquille presque vide sans aucune fiche produit. De plus, Shein challenge ou bloque le trafic qui ne ressemble pas à un vrai navigateur. Rendre la page via la Crawling API derrière une adresse IP de confiance résout les deux problèmes, c'est pourquoi le scraper présenté ici achemine sa requête par ce biais plutôt que de récupérer l'URL directement.

Comment scraper une catégorie ou une recherche Shein spécifique ?

Pointez le scraper vers l'URL de catégorie, par exemple /Women-Clothing-c-2030.html, ou vers une URL de recherche comme /pdsearch/dress/. Les deux rendent la même grille de fiches produits, donc les mêmes sélecteurs s'appliquent. Pour couvrir plusieurs catégories, conservez une correspondance de noms vers URLs et parcourez-la, en espaçant les requêtes avec un court délai entre les pages.

Puis-je obtenir le SKU, les couleurs et les tailles pour chaque produit ?

Ces champs se trouvent sur la page de détail propre à chaque produit, pas sur la grille d'annonces. Collectez d'abord le champ link depuis l'annonce, puis récupérez chaque page produit via la même fonction crawl et analysez le SKU, la description complète, les nuanciers de couleurs et les options de tailles à partir de cette page. Les champs de l'ancien guide correspondent à un scraping en deux étapes : l'annonce pour la découverte, la page de détail pour l'approfondissement.

Comment gérer la pagination sur Shein ?

Shein pagine les annonces avec un paramètre de requête ?page=. Parcourez les pages dans l'ordre, arrêtez-vous quand une page ne retourne aucun produit et plafonnez la boucle avec un nombre maximum de pages pour qu'une exécution reste bornée. L'aide scrape_categories ci-dessus fait exactement cela, et espacer chaque requête avec un court sommeil empêche l'exécution de ressembler à du trafic en rafale.

Vaut-il mieux exporter en JSON ou en CSV ?

Les deux, et le script écrit les deux depuis les mêmes enregistrements. JSON conserve la structure imbriquée et est facile à recharger en Python, tandis que le CSV s'ouvre directement dans une feuille de calcul pour un filtrage et un graphique rapides. La liste FIELDS partagée maintient les colonnes CSV dans le même ordre que les clés du dictionnaire, de sorte que les deux fichiers ne divergent jamais.

Comment éviter d'être bloqué en scrapant Shein ?

Maintenez un faible taux de requêtes par adresse IP, ajoutez un délai entre les pages et les catégories, et acheminez via des adresses IP résidentielles rotatives de sorte qu'aucune adresse unique ne déclenche une limite de débit. La Crawling API gère la rotation, un pool d'adresses IP de confiance et la gestion des défis pour vous ; si vous construisez votre propre pile, c'est la partie sur laquelle investir. Surveillez les codes de statut et levez le pied lorsque vous commencez à voir des défis.

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