Tokopedia est l'une des plus grandes places de marché en ligne d'Indonésie, avec des dizaines de millions d'acheteurs actifs et des centaines de milliers de marchands proposant des produits dans l'électronique, la mode, l'alimentation et les articles pour la maison. Ses pages de recherche et de produits publiques sont un signal de demande riche : les titres, prix, vendeurs, notes et comptages de ventes qui apparaissent pour n'importe quelle requête sont exactement ce que les équipes utilisent pour le suivi des prix, la recherche concurrentielle et l'analyse des tendances de catégories.
Ce guide vous montre comment scraper des données Tokopedia avec JavaScript et Node.js en utilisant cheerio. Vous construisez un scraper minimal et fonctionnel qui récupère les listings de recherche et les pages produits Tokopedia via la Crawling API, analyse le titre, le prix, la boutique, la note, le nombre de ventes et le lien de chaque produit, gère la pagination et exporte le résultat en JSON et CSV. L'ensemble du tutoriel se limite aux données de listing de produits publics, et la section juridique en fin d'article vaut la peine d'être lue avant de pointer ceci vers des volumes réels.
Ce que vous allez construire
Un script Node.js qui prend une URL de recherche publique Tokopedia, récupère le HTML rendu via la Crawling API et extrait un enregistrement structuré pour chaque produit de la grille de résultats. Nous utilisons une recherche de casques audio comme exemple fil rouge et extrayons ces champs par article :
- Titre le nom du produit affiché sur la carte.
- Prix le prix tel qu'affiché, par exemple « Rp178.000 ».
- Boutique le nom du magasin ou du vendeur proposant le produit.
- Note le texte de la note en étoiles quand la carte en affiche une.
- Vendu le nombre d'unités vendues quand il est présent, par exemple « 60+ terjual ».
- Lien l'URL vers la page produit individuelle.
Pourquoi une requête classique échoue sur Tokopedia
Si vous demandez une URL de recherche Tokopedia avec un client HTTP basique, vous n'obtenez presque jamais la grille de produits en retour. Deux facteurs jouent contre vous. Premièrement, Tokopedia rend ses cartes de listing dans le navigateur avec JavaScript, donc le HTML initial est une coquille quasi vide jusqu'à ce que les scripts de la page s'exécutent et récupèrent les données produit. Deuxièmement, la plateforme signale le trafic automatisé : les IP de datacenter et les patterns de requêtes qui ne ressemblent pas à un vrai navigateur sont limités en débit ou bloqués avant d'atteindre les listings rendus.
Un scraper Tokopedia fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend réellement la page, et une IP que la plateforme perçoit comme un vrai visiteur. Vous pouvez assembler cela vous-même avec un navigateur headless et un pool de proxies résidentiels rotatifs, mais assembler ces éléments et les maintenir opérationnels représente la majeure partie du travail. La Crawling API regroupe les deux dans un seul appel : vous lui envoyez l'URL, elle rend la page derrière une IP de confiance et vous renvoie le HTML finalisé à analyser avec cheerio.
Crawlbase émet deux tokens : un token normal pour les sites statiques et un token JavaScript pour le contenu rendu par navigateur. Tokopedia charge ses produits via JavaScript, donc utilisez le token JavaScript ici. Le niveau gratuit vous donne jusqu'à 20 000 requêtes sans carte bancaire pour que vous puissiez tester l'ensemble du flux avant de payer quoi que ce soit.
Prérequis
Quelques éléments doivent être en place avant d'écrire le moindre code. Aucun ne prend longtemps.
Notions de base en JavaScript et Node.js. Vous devez être à l'aise pour écrire et exécuter un script Node et installer des packages avec npm. Si vous débutez avec Node, le guide pour construire un scraper web avec Node.js couvre les bases que ce tutoriel suppose.
Node.js 16 ou supérieur. Confirmez votre version avec node --version. Si vous ne l'avez pas, installez-le depuis le site de Node.js ou via un gestionnaire de versions comme nvm.
Un compte Crawlbase et un token. Inscrivez-vous, ouvrez votre tableau de bord et copiez votre token JavaScript. Le niveau gratuit vous donne jusqu'à 20 000 requêtes sans carte bancaire. 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 dossier de projet, initialisez-le et installez les deux bibliothèques dont le scraper a besoin.
node --version mkdir tokopedia-scraper && cd tokopedia-scraper npm init -y npm install crawlbase cheerio
Deux dépendances font le travail : crawlbase est le client Node officiel pour la Crawling API, et cheerio analyse le HTML retourné avec une API de style jQuery pour que vous puissiez extraire chaque champ par sélecteur CSS. Créez un fichier nommé tokopedia-scraper.js dans ce dossier et ajoutez le code des étapes ci-dessous.
Étape 1 : récupérer la page de recherche rendue
Commencez par obtenir la page finalisée. Importez la classe CrawlingAPI, initialisez-la avec votre token et demandez l'URL de recherche. Tokopedia charge les résultats de façon paresseuse, donc passez ajax_wait et un délai page_wait pour laisser le temps à la page de se rendre avant que l'API la capture. Vérifier le code de statut avant d'analyser permet de détecter les erreurs clairement plutôt qu'en silence.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const options = { ajax_wait: 'true', page_wait: '5000' }; const searchURL = 'https://www.tokopedia.com/search?q=headset'; api .get(searchURL, options) .then((response) => { if (response.statusCode === 200) { console.log(response.body.slice(0, 500)); } }) .catch((error) => console.error('API request error:', error));
Exécutez le script avec node tokopedia-scraper.js et vous devriez voir le vrai balisage produit Tokopedia en haut du body, et non une coquille vide. Cela confirme que le rendu fonctionne avant d'écrire un seul sélecteur. L'indicateur ajax_wait demande à l'API d'attendre que les requêtes internes à la page se stabilisent, et page_wait maintient un délai supplémentaire de cinq secondes pour que les cartes chargées paresseusement aient le temps d'apparaître.
Cette première requête vient de retourner une page de recherche Tokopedia entièrement rendue sans navigateur headless ni proxy de votre côté. La Crawling API exécute la page dans un vrai navigateur, attend que les cartes chargées par JavaScript se stabilisent et fait tourner les IPs résidentielles côté serveur, pour que vous obteniez le HTML finalisé en un seul appel. Pointez-la sur n'importe quelle requête de recherche publique avec le niveau gratuit d'abord.
Étape 2 : analyser chaque produit avec cheerio
Avec le HTML rendu en main, chargez-le dans cheerio et parcourez les cartes produit. Tokopedia dispose chaque résultat dans un conteneur répétitif à l'intérieur de la région des résultats de recherche, donc vous sélectionnez chaque carte, puis lisez le titre, le prix, la boutique, la note, le nombre de ventes et le lien depuis l'intérieur. Lire chaque champ de façon défensive évite qu'une valeur manquante fasse planter l'exécution.
const cheerio = require('cheerio'); function parseSearchListings(html) { const $ = cheerio.load(html); const products = []; const cards = $( 'div[data-testid="divSRPContentProducts"] div.css-5wh65g' ); cards.each((index, element) => { const card = $(element); const title = card .find('span.OWkG6oHwAppMn1hIBsC3pQ\\=\\=') .text() .trim(); const price = card .find('div.ELhJqP-Bfiud3i5eBR8NWg\\=\\=') .text() .trim(); const shop = card .find('span.X6c-fdwuofj6zGvLKVUaNQ\\=\\=') .text() .trim(); // Rating and sold count sit in small text rows under the price const rating = card.find('span.nBBbPk2cBpbZJ2nFPN8jKA\\=\\=').text().trim(); const sold = card.find('span.eLNb-rRDe6X9p64ZsQAx9w\\=\\=').text().trim(); const link = card.find('a.Nq8NlC5Hk9KgVBJzMYBUsg\\=\\=').attr('href'); if (title) { products.push({ title: title, price: price || 'N/A', shop: shop || 'N/A', rating: rating || 'N/A', sold: sold || 'N/A', link: link || 'N/A', }); } }); return products; }
Quelques détails assurent la fidélité à la page. Les cartes se trouvent sous le test id divSRPContentProducts, et chaque carte porte le titre dans un span avec la classe OWkG6oHwAppMn1hIBsC3pQ==, le prix dans un div avec la classe ELhJqP-Bfiud3i5eBR8NWg==, et le nom de la boutique dans un span avec la classe X6c-fdwuofj6zGvLKVUaNQ==. Le lien produit est lu depuis le href de l'ancre de la carte. Ces noms de classes contiennent des caractères == littéraux, donc ils sont échappés en \\=\\= dans les chaînes de sélecteur cheerio. Les sélecteurs de note et de comptage de ventes suivent le même pattern de texte court sous le prix.
Les noms de classes hachés de Tokopedia (OWkG6oHwAppMn1hIBsC3pQ== et autres) sont générés et changent sans préavis. Considérez les sélecteurs ci-dessus comme un modèle de départ, pas comme un contrat. Lorsqu'un champ revient vide, ré-inspectez la page live 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 de production, ce n'est pas le signe que quelque chose est cassé.
Étape 3 : gérer la pagination
Tokopedia répartit les résultats de recherche sur plusieurs pages, et chacune est accessible en ajoutant un paramètre page à l'URL, par exemple &page=2. Bouclez de la première page à la dernière souhaitée, récupérez chacune via la Crawling API, analysez-la avec la fonction de l'étape 2 et collectez tout dans un seul tableau. Si une page échoue à se récupérer, arrêtez tôt plutôt que d'ajouter des résultats vides.
async function fetchHtml(url) { const response = await api.get(url, options); if (response.statusCode === 200) return response.body; console.error(`Failed to fetch page: ${response.statusCode}`); return null; } async function scrapeMultiplePages(baseUrl, maxPages) { const allProducts = []; for (let page = 1; page <= maxPages; page++) { const paginatedUrl = `${baseUrl}&page=${page}`; const html = await fetchHtml(paginatedUrl); if (!html) break; const products = parseSearchListings(html); allProducts.push(...products); console.log(`Page ${page}: ${products.length} products`); } return allProducts; }
Cela boucle sur les pages demandées, scrape les listings de chacune et agrège les résultats. Comme chaque page de recherche partage la même structure de carte, le parser écrit à l'étape 2 fonctionne sur toutes sans modification.
Étape 4 : assembler le script complet avec export JSON et CSV
Câblez maintenant la récupération, le parser et la pagination dans un script fonctionnel, puis écrivez les enregistrements sur disque en JSON et CSV. Le JSON conserve la structure imbriquée complète ; le CSV s'intègre directement dans un tableur.
const fs = require('fs'); const { CrawlingAPI } = require('crawlbase'); const cheerio = require('cheerio'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const options = { ajax_wait: 'true', page_wait: '5000' }; // Paste parseSearchListings, fetchHtml, and scrapeMultiplePages here function toCsv(rows) { const headers = ['title', 'price', 'shop', 'rating', 'sold', 'link']; const escape = (value) => `"${String(value).replace(/"/g, '""')}"`; const lines = [headers.join(',')]; for (const row of rows) { lines.push(headers.map((h) => escape(row[h])).join(',')); } return lines.join('\n'); } async function main() { const baseUrl = 'https://www.tokopedia.com/search?q=headset'; const maxPages = 5; const products = await scrapeMultiplePages(baseUrl, maxPages); fs.writeFileSync( 'tokopedia_search_results.json', JSON.stringify(products, null, 2) ); fs.writeFileSync('tokopedia_search_results.csv', toCsv(products)); console.log(`Saved ${products.length} products to JSON and CSV`); } main();
Collez les fonctions parseSearchListings, fetchHtml et scrapeMultiplePages dans le même fichier pour que main puisse les appeler. Exécutez-le avec node tokopedia-scraper.js et vous obtenez deux fichiers : tokopedia_search_results.json avec les enregistrements structurés complets et tokopedia_search_results.csv prêt à ouvrir dans un tableur. Le helper toCsv met chaque champ entre guillemets et double les guillemets intégrés, ce qui est important ici car les titres Tokopedia sont longs et contiennent fréquemment des virgules.
À quoi ressemble la sortie
Le fichier JSON contient un objet par produit dans l'ordre de recherche, chacun avec le titre, le prix, la boutique, la note, le nombre de ventes et le lien.
[ { "title": "Ipega PG-R008 Gaming Headset for P4 /X1 series/N-Switch Lite/Mobile", "price": "Rp178.000", "shop": "ipegaofficial", "rating": "4.9", "sold": "250+ terjual", "link": "https://www.tokopedia.com/ipegaofficial/ipega-pg-r008-gaming-headset" }, { "title": "Hippo Toraz Handsfree Earphone Stereo Sound - headset, Putih", "price": "Rp13.000", "shop": "HippoCenter", "rating": "4.8", "sold": "1rb+ terjual", "link": "https://www.tokopedia.com/hippocenter88/hippo-toraz-handsfree-earphone" } ]
Le CSV reflète les mêmes lignes avec une ligne d'en-tête, il peut donc être directement importé dans Excel, Google Sheets ou tout pipeline de données qui lit des fichiers délimités.
title,price,shop,rating,sold,link "Ipega PG-R008 Gaming Headset for P4 /X1 series","Rp178.000","ipegaofficial","4.9","250+ terjual","https://www.tokopedia.com/ipegaofficial/ipega-pg-r008-gaming-headset" "Hippo Toraz Handsfree Earphone Stereo Sound - headset, Putih","Rp13.000","HippoCenter","4.8","1rb+ terjual","https://www.tokopedia.com/hippocenter88/hippo-toraz-handsfree-earphone"
Scraper des pages produits individuelles
Les listings de recherche donnent de la largeur ; les pages produits donnent de la profondeur. Une fois que vous avez un lien depuis le scraper de recherche, vous pouvez récupérer la page produit via la même Crawling API et extraire des champs plus riches. Sur une page produit Tokopedia, le nom se trouve dans un h1 avec data-testid="lblPDPDetailProductName", le prix dans un div avec data-testid="lblPDPDetailProductPrice", la boutique dans un a avec data-testid="llbPDPFooterShopName", la description dans un div avec data-testid="lblPDPDescriptionProduk", et les images miniatures dans des balises img à l'intérieur des boutons data-testid="PDPImageThumbnail".
async function scrapeProductPage(url) { const html = await fetchHtml(url); if (!html) return null; const $ = cheerio.load(html); const images = $('button[data-testid="PDPImageThumbnail"] img') .map((i, el) => $(el).attr('src')) .get(); return { name: $('h1[data-testid="lblPDPDetailProductName"]').text().trim(), price: $('div[data-testid="lblPDPDetailProductPrice"]').text().trim(), shop: $('a[data-testid="llbPDPFooterShopName"]').text().trim(), description: $('div[data-testid="lblPDPDescriptionProduk"]').text().trim(), images: images, }; }
Cela réutilise le même helper fetchHtml du scraper de recherche, donc le scraper de pages produits hérite du rendu et de la rotation IP sans configuration supplémentaire. Alimentez-le avec n'importe quel lien collecté par le scraper de recherche et il retourne un objet structuré unique que vous pouvez stocker de la même façon, avec JSON.stringify ou une ligne dans votre CSV.
Rester non bloqué
Même avec le rendu géré, Tokopedia surveille le trafic ressemblant à un scraper. Quelques habitudes maintiennent une exécution saine, et elles s'appliquent à toute cible commerciale difficile.
- Cadencez vos requêtes. Introduisez un délai entre les récupérations de pages plutôt que de marteler les résultats de recherche en boucle serrée. Étaler les requêtes est le facteur le plus important pour rester sous les limites de débit de la plateforme.
- Misez sur la rotation. Un pool d'IPs résidentielles répartit les requêtes sur de nombreuses adresses d'utilisateurs réels pour qu'aucune seule ne déclenche une limite. La Crawling API s'en charge pour vous ; si vous construisez votre propre stack, c'est la partie à maîtriser.
- Lisez les codes de statut. Une exécution qui commence à retourner des réponses non-200 vous signale que le débit actuel ou le niveau d'IP n'est plus suffisant. Traitez cela comme un signal de ralentissement, pas du bruit à ignorer.
Pour le guide complet, consultez comment scraper des sites web sans se faire bloquer et le guide plus approfondi sur le crawling de sites JavaScript, qui couvrent tous les deux le côté rendu et rotation plus en détail.
Est-il légal de scraper Tokopedia ?
La légalité du scraping de Tokopedia dépend des conditions d'utilisation de Tokopedia, de votre juridiction et de ce que vous faites des données. Les conditions de Tokopedia 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 générales de Tokopedia et son fichier robots.txt, et traitez les deux comme la frontière de ce que vous collectez.
Quelques règles à respecter. Collectez uniquement les données publiques des produits : le titre, le prix, le nom de la boutique, la note, le nombre de ventes et le lien produit que quiconque peut voir sur une page de recherche ou de produit sans compte. Respectez les attentes de débit de Tokopedia et gardez votre volume de requêtes suffisamment bas pour ne pas surcharger ses serveurs. Évitez les données personnelles, notamment tout ce qui est lié à des acheteurs ou des évaluateurs identifiables au-delà du texte d'avis public et des comptages de notes affichés sur la page. Ne redistribuez pas les médias protégés par le droit d'auteur de Tokopedia, comme la photographie de produit des marchands, comme s'ils vous appartenaient.
Ce guide est délibérément limité aux recherches publiques et aux listings de produits, car c'est la ligne qui rend le travail défendable. Il ne couvre rien derrière une connexion, les données personnelles d'acheteurs ou de vendeurs, l'historique de commandes, les chats, ni aucune tentative de contourner une authentification ou un CAPTCHA que vous n'étiez pas censé passer. Si votre projet a besoin de plus que des listings publics, la bonne voie est un accord de données sanctionné ou tout canal API officiel que Tokopedia propose, pas un scraper plus sophistiqué. En cas de doute, préférez la permission à l'hypothèse que le silence vaut consentement.
Points clés
- Tokopedia rend les listings côté client et limite fortement le débit. Une requête simple retourne une coquille vide, vous devez donc rendre la page derrière une IP de confiance avant de l'analyser, en utilisant le token JavaScript.
-
La Crawling API fait les deux en un seul appel. Elle rend la page avec
ajax_waitetpage_wait, fait tourner les IPs résidentielles et vous restitue le HTML finalisé à analyser avec cheerio. -
cheerio extrait les champs. Sélectionnez chaque carte produit, puis lisez le titre, le prix, la boutique, la note, le nombre de ventes et le lien, en échappant les noms de classes hachés
==et en anticipant leur dérive au fil du temps. -
La pagination et les pages produits étendent le scraper. Bouclez sur le paramètre
pagepour la largeur, puis réutilisez le même helper de récupération pour extraire le nom, le prix, la boutique, la description et les images des pages produits individuelles. - Restez sur les données publiques. Respectez les CGU et le robots.txt de Tokopedia, cadencez vos requêtes, exportez en JSON et CSV, et évitez tout ce qui est derrière une connexion ou toute donnée personnelle.
Foire aux questions
Est-il légal de scraper des données depuis Tokopedia ?
Le scraping de Tokopedia peut être admissible si vous restez sur les données publiques des produits et respectez les conditions d'utilisation de Tokopedia. Examinez d'abord les règles du site et son fichier robots.txt, gardez votre volume de requêtes raisonnable et évitez les données personnelles ou derrière connexion. Utilisez ce que vous collectez à des fins légitimes comme la recherche, le suivi des prix ou l'analyse, et non pour quoi que ce soit qui viole les politiques de Tokopedia ou la législation locale.
Pourquoi ai-je besoin de la Crawling API pour scraper Tokopedia ?
Tokopedia charge ses produits via JavaScript, donc une requête HTTP brute retourne généralement une coquille vide plutôt que les cartes produit. La Crawling API rend la page dans un vrai navigateur, attend le contenu chargé paresseusement avec ajax_wait et page_wait, et fait tourner les IPs résidentielles pour que vous atteigniez les listings finalisés sans gérer une flotte de navigateurs ni un pool de proxies.
Quels points de données puis-je extraire de Tokopedia ?
Depuis les listings de recherche, vous pouvez récupérer le titre du produit, le prix, le nom de la boutique, la note, le nombre de ventes et le lien. Depuis les pages produits individuelles, vous pouvez extraire le nom, le prix, la boutique, la description complète et les URLs des images. Ensemble, ils couvrent les champs publics dont la plupart des équipes ont besoin pour le suivi des prix, la recherche concurrentielle et l'analyse des tendances de produits.
Pourquoi mes sélecteurs Tokopedia retournent-ils des valeurs vides ?
Très probablement le balisage a changé. Les noms de classes hachés de Tokopedia comme OWkG6oHwAppMn1hIBsC3pQ== sont générés et changent sans préavis, donc des sélecteurs qui fonctionnaient le mois dernier peuvent être cassés. Ré-inspectez une page live dans les outils de développement de votre navigateur et mettez à jour les sélecteurs. La maintenance périodique des sélecteurs est normale pour tout scraper de production.
Comment gérer la pagination sur les résultats de recherche Tokopedia ?
Ajoutez un paramètre page à l'URL de recherche, par exemple &page=2, et bouclez de la première page à la dernière souhaitée. Récupérez chaque page via la Crawling API, analysez-la avec la même fonction cheerio et collectez les résultats dans un tableau avant d'exporter. Arrêtez tôt si une page échoue à se récupérer pour ne pas rembourrer vos données avec des résultats vides.
Puis-je scraper les données personnelles des acheteurs ou des vendeurs depuis Tokopedia ?
Non, et ce guide ne le couvre pas. Les comptes acheteurs, l'historique de commandes, les chats et tout ce qui est derrière une connexion ne sont pas des données publiques. Scraper du contenu derrière connexion, des données personnelles sur les acheteurs ou les évaluateurs au-delà du texte d'avis public, ou contourner l'authentification est hors de portée ici et va à l'encontre des conditions de Tokopedia. Pour des besoins plus larges, consultez le guide sur le web scraping e-commerce ou la vue d'ensemble du web scraping pour l'intelligence des prix, et préférez un accord de données sanctionné pour tout ce qui dépasse les listings publics.
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.
