Avertissement légal : Ce guide couvre uniquement l'accès à des données publiques sur Pinterest. Vous devez respecter les Conditions d'utilisation de Pinterest, le Computer Fraud and Abuse Act (CFAA) aux États-Unis et le RGPD en Europe. Ne scrapez jamais de données personnelles ni de contenu protégé par connexion sans autorisation explicite. Pour un usage en production, préférez l'API officielle Pinterest v5.
Vous construisez un jeu de données de tendances visuelles, de catalogues e-commerce ou de signaux marketing. Pinterest est une mine d'or : plus de 498 millions d'utilisateurs actifs mensuels publient des épingles (pins) organisées en tableaux (boards). Mais scraper Pinterest en 2026 demande de comprendre son API interne, ses mécanismes anti-bot et l'importance des proxies résidentiels localisés. Voici comment scraper Pinterest efficacement et de manière responsable.
Comment scraper Pinterest pins et tableaux en 2026 : ce qu'il faut savoir
Pinterest expose deux surfaces distinctes. La surface publique comprend les pages de pins individuels (/pin/{id}/), les flux de tableaux publics (/{username}/{board_slug}/) et les pages de résultats de recherche (/search/pins/?q=...). Ces pages sont accessibles sans connexion et indexées par les moteurs de recherche.
La surface privée comprend le flux d'accueil personnalisé, les recommandations basées sur l'historique de l'utilisateur et les tableaux secrets. Ces contenus nécessitent une connexion et ne doivent jamais être scrapés sans autorisation.
L'API officielle Pinterest v5 existe mais reste limitée : elle impose des quotas stricts (environ 1 000 requêtes par minute pour les comptes standards), ne donne accès qu'aux boards et pins de l'application elle-même, et ne couvre pas la recherche publique de pins. Pour construire des datasets de tendances visuelles à grande échelle, l'API interne Resource devient nécessaire.
Surfaces publiques vs privées sur Pinterest
| Surface | Accessible sans login | Endpoint concerné | Légal à scraper ? |
|---|---|---|---|
| Pin individuel public | Oui | /pin/{id}/ | Oui (données publiques) |
| Tableau public | Oui | /{user}/{board}/ | Oui (données publiques) |
| Recherche de pins | Oui | /search/pins/?q= | Oui (résultats publics) |
| Flux d'accueil | Non | HomeFeed | Non sans autorisation |
| Tableau secret | Non | BoardResource | Non |
Comprendre l'API interne Resource de Pinterest
Pinterest utilise une API interne appelée Resource API pour charger dynamiquement le contenu de ses pages. Chaque page publique fait des appels XHR vers des endpoints comme /resource/PinResource/get/, /resource/BoardFeedResource/get/ ou /resource/SearchResource/get/. Ces endpoints retournent du JSON avec les données des pins.
La structure typique d'une requête ressemble à ceci :
GET /resource/BoardFeedResource/get/?source_url=/{username}/{board_slug}/&data={"options":{"board_id":"123456789012345678","page_size":25,"bookmarks":["YXJlYXNvbmFibGU..."}}
Le paramètre source_url indique la page d'origine, et data contient un objet JSON encodé en URL avec les options de pagination. Les en-têtes requis incluent :
- X-Pinterest-PWS-Handler : identifie le handler côté serveur (ex.
www/[username]/[board].js). - X-APP-VERSION : version du frontend (ex.
b8e26a9), visible dans le HTML de la page. - csrftoken : token anti-CSRF présent dans le cookie
csrftokende la page initiale. - User-Agent : un navigateur réaliste et cohérent avec les autres en-têtes.
Sans ces en-têtes, Pinterest renvoie des erreurs 403 ou des réponses vides. Le token CSRF impose en outre de maintenir une session cohérente entre la requête initiale de la page et les appels Resource suivants.
Réalité anti-bot : rate limits, bot scoring et localisation
Pinterest applique des limites de débit par adresse IP et un système de scoring anti-bot. D'après des observations empiriques de la communauté open-source, un seuil approximatif se situe autour de 50 à 100 requêtes par minute par IP avant que Pinterest ne commence à servir des CAPTCHA ou des réponses tronquées. Au-delà de 200 requêtes/minute, l'IP est souvent temporairement bloquée.
Le bot scoring prend en compte plusieurs signaux :
- Cohérence du User-Agent avec les en-têtes
Accept,Accept-LanguageetSec-Fetch-*. - Présence et validité du
csrftokendans les cookies. - Pattern temporel des requêtes (trop régulier = suspect).
- Concordance entre
source_urlet l'en-têteReferer. - Localisation géographique de l'IP (un IP allemand demandant des résultats en français est suspect).
C'est ici que les proxies résidentiels rotatifs deviennent indispensables. La recherche et les recommandations Pinterest sont localisées : un utilisateur américain voit des pins différents d'un utilisateur français pour la même requête. Pour capturer des tendances régionales, vous devez géo-cibler vos proxies avec un flag comme -country-US ou -country-FR.
Comparaison des types de proxies pour Pinterest
| Type | Détection | Localisation | Coût | Recommandé pour Pinterest |
|---|---|---|---|---|
| Datacenter | Facile à détecter | Limitée | Bas | Non — blocage rapide |
| Mobile (4G/5G) | Très difficile | Précise | Élevé | Oui — usage intensif |
| Résidentiel rotatif | Difficile | Pays/ville | Moyen | Oui — meilleur compromis |
Les proxies résidentiels offrent le meilleur compromis coût/fiabilité pour la plupart des cas d'usage de Pinterest API scraping. Consultez notre tarification pour les options disponibles.
Implémentation pratique : scraper un Board Feed en Python
Voici un exemple complet en Python utilisant requests et le proxy HTTP de ProxyHat sur gate.proxyhat.com:8080. Le script récupère la page initiale d'un tableau, extrait le csrftoken, puis pagine via BoardFeedResource en utilisant le système de bookmarks.
import requests
import json
import time
import random
from urllib.parse import quote
PROXY = "http://user-country-US-session-board1:pass@gate.proxyhat.com:8080"
proxies = {"http": PROXY, "https": PROXY}
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Language": "en-US,en;q=0.9",
"X-Pinterest-PWS-Handler": "www/[username]/[board].js",
"X-Requested-With": "XMLHttpRequest",
}
BASE = "https://www.pinterest.com"
board_url = "/username/board-slug/"
# 1. Charger la page initiale pour récupérer csrftoken et app_version
session = requests.Session()
session.proxies = proxies
session.headers.update(HEADERS)
resp = session.get(BASE + board_url, timeout=30)
if resp.status_code != 200:
print(f"Erreur {resp.status_code} sur la page initiale")
exit(1)
# Extraire csrftoken depuis les cookies
csrf = session.cookies.get("csrftoken", "")
# Extraire l'app version depuis le HTML (ex. "b8e26a9")
import re
m = re.search(r'"app_version":"([a-f0-9]+)"', resp.text)
app_version = m.group(1) if m else "b8e26a9"
# Extraire le board_id depuis le JSON embarqué
m2 = re.search(r'"board_id":"(\d+)"', resp.text)
board_id = m2.group(1) if m2 else None
if not board_id:
print("Impossible de trouver board_id")
exit(1)
session.headers.update({
"X-APP-VERSION": app_version,
"X-CSRFToken": csrf,
"Referer": BASE + board_url,
})
# 2. Paginer BoardFeedResource
all_pins = []
bookmarks = [""]
page_size = 25
max_pages = 10
for page in range(max_pages):
data_param = json.dumps({
"options": {
"board_id": board_id,
"page_size": page_size,
"bookmarks": bookmarks,
},
"context": {}
})
resource_url = f"{BASE}/resource/BoardFeedResource/get/?source_url={quote(board_url)}&data={quote(data_param)}"
resp = session.get(resource_url, timeout=30)
if resp.status_code != 200:
print(f"Page {page}: HTTP {resp.status_code} — pause prolongée")
time.sleep(30)
continue
payload = resp.json()
pins = payload.get("resource_response", {}).get("data", [])
for pin in pins:
# Pin tronqué : id, title, image url, link
all_pins.append({
"id": pin.get("id", ""),
"title": pin.get("title", ""),
"image_url": pin.get("images", {}).get("orig", {}).get("url", ""),
"link": pin.get("link", ""),
})
# Récupérer le bookmark pour la page suivante
bm_list = payload.get("resource", {}).get("options", {}).get("bookmarks", [])
if not bm_list or bm_list == [""]:
print("Pagination terminée")
break
bookmarks = bm_list
# Pacing : 2-5 secondes entre les pages
time.sleep(random.uniform(2, 5))
print(f"Total pins récupérés : {len(all_pins)}")
for p in all_pins[:3]:
print(json.dumps(p, indent=2, ensure_ascii=False))
Notez l'utilisation du flag -session-board1 dans le nom d'utilisateur ProxyHat : cela maintient la même IP résidentielle pour toute la session, ce qui préserve la continuité du csrftoken. Sans session collante (sticky session), chaque requête proviendrait d'une IP différente et Pinterest invaliderait le token CSRF.
Exemple Node.js : recherche de pins via le gateway HTTP
Voici l'équivalent en Node.js avec axios et un proxy HTTPS via le gateway ProxyHat sur le port 8080. Cet exemple interroge SearchResource pour récupérer des pins publics correspondant à une requête.
const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');
const PROXY_URL = 'http://user-country-FR-session-search1:pass@gate.proxyhat.com:8080';
const agent = new HttpsProxyAgent.HttpsProxyAgent(PROXY_URL);
const BASE = 'https://www.pinterest.com';
const SEARCH_TERM = 'decoration interieur';
const sourceUrl = `/search/pins/?q=${encodeURIComponent(SEARCH_TERM)}`;
async function scrapePinterestSearch() {
const session = axios.create({
httpsAgent: agent,
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'fr-FR,fr;q=0.9',
'X-Pinterest-PWS-Handler': 'www/search.js',
'X-Requested-With': 'XMLHttpRequest',
},
timeout: 30000,
});
// 1. Page de recherche initiale
const pageResp = await session.get(BASE + sourceUrl);
if (pageResp.status !== 200) {
throw new Error(`Page initiale échouée: ${pageResp.status}`);
}
const csrfMatch = pageResp.headers['set-cookie']
?.join('; ')
.match(/csrftoken=([^;]+)/);
const csrf = csrfMatch ? csrfMatch[1] : '';
const versionMatch = pageResp.data.match(/"app_version":"([a-f0-9]+)"/);
const appVersion = versionMatch ? versionMatch[1] : 'b8e26a9';
// 2. Appel SearchResource
const dataParam = encodeURIComponent(JSON.stringify({
options: {
query: SEARCH_TERM,
page_size: 25,
bookmarks: [''],
},
context: {},
}));
const resourceUrl = `${BASE}/resource/SearchResource/get/?source_url=${encodeURIComponent(sourceUrl)}&data=${dataParam}`;
const resp = await session.get(resourceUrl, {
headers: {
'X-APP-VERSION': appVersion,
'X-CSRFToken': csrf,
'Referer': BASE + sourceUrl,
},
});
const pins = resp.data.resource_response?.data || [];
const results = pins.map(pin => ({
id: pin.id,
title: pin.title || '',
image_url: pin.images?.orig?.url || '',
link: pin.link || '',
}));
console.log(`Pins trouvés: ${results.length}`);
console.log(JSON.stringify(results.slice(0, 3), null, 2));
}
scrapePinterestSearch().catch(console.error);
Pagination par bookmarks, sessions collantes et hygiène de fingerprint
Le système de bookmarks
Pinterest n'utilise pas de pagination par offset classique. Chaque réponse contient un champ bookmarks dans resource.options.bookmarks — une chaîne encodée (souvent en base64) qui sert de curseur opaque. Vous devez renvoyer ce bookmark tel quel dans la requête suivante. Quand le bookmark revient vide ou égal à [""], la pagination est terminée.
Ne tentez jamais de forger ou d'incrémenter un bookmark vous-même : il est signé côté serveur et toute altération provoque une erreur 400.
Sessions collantes (sticky sessions)
Le csrftoken est lié à la session IP. Si votre proxy rotatif change d'IP à chaque requête, Pinterest verra un token CSRF provenant d'une IP différente de celle qui l'a émis, et renverra 403 Forbidden. La solution : utiliser une session collante via le flag ProxyHat -session-{id}, qui maintient la même IP résidentielle pendant toute la durée du scraping d'un board ou d'une recherche.
Exemple de nom d'utilisateur avec session : user-country-US-session-board123:pass
Changez d'ID de session entre différents boards ou recherches pour faire tourner l'IP, mais gardez le même ID pendant toute la pagination d'un même flux.
Pacing et temporisation
- 2 à 5 secondes entre les pages d'un même flux.
- 10 à 30 secondes de pause si vous recevez un
429ou un403. - Ne dépassez pas 50 requêtes/minute par IP/session.
- Ajoutez du jitter aléatoire pour éviter des patterns trop réguliers.
Hygiène du User-Agent et des en-têtes
Le fingerprint HTTP doit être cohérent. Si vous déclarez un User-Agent Chrome sur Windows, vos en-têtes Sec-CH-UA, Sec-CH-UA-Platform et Accept-Language doivent correspondre. Pinterest croise ces signaux. Un User-Agent Chrome avec un Accept-Language japonais et une IP américaine est immédiatement suspect.
Bonnes pratiques :
- Gardez le même User-Agent pour toute la durée d'une session.
- Faites correspondre
Accept-Languageau pays du proxy (ex.fr-FRpour-country-FR). - Incluez les en-têtes
Sec-Fetch-Site: same-originetSec-Fetch-Mode: corspour les appels Resource. - N'envoyez pas d'en-têtes de navigateur mobile si vous utilisez un User-Agent desktop.
Pour plus de détails sur la configuration des proxies et la géo-localisation, consultez notre documentation officielle et la page des localisations disponibles.
Scraping éthique et quand utiliser l'API officielle
Le scraping de Pinterest soulève des questions éthiques et légales importantes. Voici nos recommandations :
Règles de base
- Données publiques uniquement : ne scrapez que les pins et tableaux accessibles sans connexion.
- Pas de données personnelles : évitez de collecter des informations identifiant des individus (noms, emails, localisation précise).
- Respectez
robots.txt: consultezhttps://www.pinterest.com/robots.txtet respectez les règlesDisallow. - Limitez le débit : un scraping agressif dégrade l'expérience pour tous les utilisateurs et peut être considéré comme un abus.
- Ne redistribuez pas le contenu : les images et textes de pins sont soumis au droit d'auteur. Collectez les métadonnées (titres, liens, descriptions) pour l'analyse, pas les fichiers binaires.
Quand préférer l'API officielle Pinterest v5
L'API officielle Pinterest v5 est le bon choix pour :
- La gestion de votre propre compte Pinterest (pins, boards, analytics).
- Les intégrations e-commerce synchronisées avec votre catalogue.
- Les applications de production nécessitant un support et une stabilité garantie.
Le scraping de l'API interne Resource reste pertinent pour :
- La recherche de tendances visuelles à grande échelle (non couverte par l'API v5).
- L'analyse de marché concurrentiel sur des boards publics.
- La collecte de données de recherche localisées.
Dans tous les cas, documentez votre conformité aux Conditions d'utilisation de Pinterest et au RGPD si vous opérez en Europe. Pour en savoir plus sur les bonnes pratiques de scraping, consultez notre guide sur le web scraping et le suivi SERP.
Points clés à retenir
Key Takeaways :
- Pinterest expose une API interne Resource (
PinResource,BoardFeedResource,SearchResource) accessible sans login pour les données publiques.- Les en-têtes
X-Pinterest-PWS-Handler,X-APP-VERSIONetcsrftokensont obligatoires pour les appels Resource.- La pagination se fait par bookmarks opaques, pas par offset. Ne jamais forger un bookmark.
- Utilisez des proxies résidentiels rotatifs avec géo-localisation (
-country-US,-country-FR) car la recherche Pinterest est localisée.- Les sessions collantes (
-session-{id}) sont indispensables pour préserver la continuité ducsrftoken.- Limitez à 50 requêtes/minute par IP, avec du jitter aléatoire de 2 à 5 secondes entre les pages.
- Pour la production, préférez l'API officielle Pinterest v5. Le scraping de l'API interne est pertinent pour la recherche de tendances à grande échelle.
- Scrapez uniquement des données publiques et non personnelles. Respectez le RGPD et le CFAA.






