Scraping des données de compte
Présentation
L'utilisateur se connecte manuellement dans le navigateur Playwright ; vous trouvez la source de données que les propres pages du site utilisent et la rejouez à l'intérieur de la page (cookies de session + en-têtes réels), en sauvegardant les réponses brutes sur le disque. Ne manipulez jamais les identifiants.
Quand l'utiliser
- « Récupère mon historique », « scrape mes commandes/trajets/réservations », « utilise ce dépôt de scraping »
- Anciens dépôts de scraping (requêtes + mot de passe/OTP de connexion) : lisez-les sur GitHub pour les noms d'endpoints et les sélecteurs uniquement. Ne les exécutez jamais — les contrôles anti-bot (HTTP 202 corps vide, captchas) les cassent, et ils demandent le mot de passe.
Exportation officielle d'abord. Google Takeout, « Télécharger vos données », demandes GDPR/DPDP, API publiques, reçus par email. Les exportations lentes prennent des jours — demandez à l'utilisateur d'en demander une au début, puis scrapez maintenant et recoupez par ID quand elle arrive.
Flux de travail
- Ajoutez le répertoire de sortie au gitignore avant d'écrire quoi que ce soit (
data/<service>/ou l'équivalent du projet) ; confirmez avecgit check-ignore. Les données brutes contiennent des adresses, des téléphones, du GPS. - Naviguez, passez la main pour la connexion. Ouvrez la page de compte ; dites à l'utilisateur de taper son téléphone/mot de passe/OTP dans la fenêtre du navigateur et de répondre quand c'est fait. Ne demandez jamais de codes dans le chat.
- Découvrez la source (
browser-snippets.md§1). Rechargez avec un écouteur et classez :- JSON XHR/fetch (meilleur) — notez l'endpoint de liste, la forme de pagination (
next_url/curseur,page_number, décalage = dernier id,endOfList), et l'endpoint de détail (ouvrez un élément). - GraphQL — un
POST /graphql; enregistrez le corps complet de la requête (operationName, query ou hash de requête persistée, variables). - HTML rendu côté serveur — les données arrivent dans la réponse
document; récupérez les pages de liste et de détail dans la page et analysez-les avecDOMParser; sauvegardez aussi le HTML brut pour pouvoir le ré-analyser. - Listes partitionnées — si la liste est divisée par un filtre (liste déroulante d'année, plage de dates, onglets comme archivé/annulé/numérique), lisez chaque valeur de filtre et paginez chacune.
- JSON XHR/fetch (meilleur) — notez l'endpoint de liste, la forme de pagination (
- Authentification. Essayez d'abord
fetch(url, {credentials: 'include'}). Si cela retourne 401/403/vide, copiez les en-têtes non-navigateur d'une requête en direct (§2) — copiez, ne devinez jamais les valeurs. Enregistrez les noms des en-têtes uniquement ; n'imprimez ni ne sauvegardez jamais les valeurs. - Paginez en arrière-plan dans la page (§2) :
window.__x = {running, pages, error}, 1,5 s entre les requêtes, tentatives, interrogez avec de courtes évaluations. Chaque réponse : si c'est une page de connexion/captcha (l'URL contient signin/captcha, ou HTML au lieu du JSON attendu), définissezerroret arrêtez — ces réponses reviennent souvent avec un code 200. - Sauvegardez avant de naviguer (§3). Tout
goto/rechargement effacewindow.browser_evaluateavec un cheminfilenameabsolu, retournant un objet (JSON.stringifydouble-encode). ~5 Mo par fichier est acceptable ; divisez par lot au-delà. - Requêtes signées/non rejouables (en-têtes de signature de requête, corps nonce, requêtes persistées qui rejettent les modifications) : visitez chaque page de détail et capturez passivement ses réponses (§4).
- Construisez + vérifiez (ci-dessous) avec un script d'analyse en dehors du répertoire de données, puis une note d'analyse. Suivez la disposition existante du dépôt s'il y en a une (par exemple
tools/<service>/build_db.py, notes à côté des données) ; sinon demandez.
Lecture seule. Ne rejouez que ce que la page demande elle-même pour afficher les données. GraphQL : jugez par l'opération (query/Get*/List*), jamais mutation. Ne réordonnez, n'annulez, ne notez, n'archivez, ne supprimez jamais.
Vérification — faites toutes ces étapes
| Vérification | Pourquoi |
|---|---|
| La pagination s'est terminée parce que le curseur/la liste était épuisé, pas à cause d'une erreur ou d'une redirection de connexion | Troncature silencieuse |
| Cherchez le texte « voir les commandes plus anciennes dans l'application » à la fin | Les vues Web limitent l'historique (Swiggy : ~11 mois) |
| Ne vous fiez pas uniquement à l'endpoint de compte ou à l'en-tête du site | Blinkit en annonçait 40 ; la liste en avait 83 |
| Les composants totalisent le montant par ligne (articles + frais − réductions = payé) | Détecte la dérive de l'analyseur ; si le site omet des lignes pour les anciens enregistrements, dites-le — ne forcez pas |
| Les prix des articles totalisent le total de l'article | Confusion prix unitaire vs total de ligne |
| ID uniques ; déduplication des doublons exacts | Les exportations et les reçus doublonnent |
| Vérification croisée avec une autre source par ID (exportation, reçus) | Prouve la couverture |
| Chaque liste/onglet/filtre a été couvert (archivé, annulé, autres années, sous-services) | « Toutes les commandes » couvre souvent plusieurs listes |
Notes d'analyse
- API d'interface utilisateur pilotée par le serveur (
snippets,widgets,widget_type,layout) : parcourez les widgets dans l'ordre, collectez les champstextde chaque widget, mappez par étiquettes connues. Un widget à un seul texte est souvent une étiquette pour le suivant — liste blanche des noms d'étiquettes ou chaque champ se décale. - Les montants peuvent être en paise/centimes ; « GRATUIT » = 0 ; « - » en tête = réduction ; supprimez les symboles monétaires et le regroupement des virgules indiennes. Gardez les devises séparées.
- Horodatages : achats → fuseau horaire de l'utilisateur ; trajets/voyages → l'heure locale de l'enregistrement.
- Conservez les fichiers bruts datés (
orders-raw-YYYY-MM-DD.json) à côté du SQLite construit.
Git
Validez uniquement : la ligne gitignore, le script d'analyse, tout README/ligne d'index. Les fichiers bruts et le SQLite restent locaux. Stagiez les chemins explicites (jamais git add -A dans un arbre sale) ; ne validez que lorsque demandé.
Erreurs courantes
- Une longue boucle d'évaluation synchrone — expire ; mettez-la en arrière-plan et interrogez.
- Retourner des données volumineuses dans le chat au lieu de
filename. - Écouteurs de snippets laissés attachés —
page.offles, ou les exécutions répétées empilent les gestionnaires. - Filtrer la découverte sur xhr/fetch sur un site rendu en HTML et conclure « aucune source de données ».