Instagram est l'une des surfaces les plus riches en données sur le web public, et c'est aussi l'une des plus difficiles à lire de manière programmatique. Les profils et les publications se rendent côté client en JavaScript, la plateforme challenge le trafic automatisé de manière agressive, et une simple requête HTTP vers une URL de profil renvoie généralement une coquille presque vide. Ce guide vous explique comment scraper des données Instagram avec Python d'une manière qui fonctionne réellement, en restant strictement dans le périmètre des données publiques.

Pour être clair d'emblée : tout ce qui est présenté ici se limite aux données publiques de comptes publics uniquement. Cela signifie les champs de profil publics, les légendes de publications publiques, les comptages publics de likes et de commentaires, et les URLs de publications publiques. Cela ne couvre pas les comptes privés, le contenu protégé par une connexion, les messages directs, les listes de followers, ni aucune donnée personnelle de personnes individuelles. Instagram et sa société mère Meta restreignent l'accès automatisé dans leurs conditions d'utilisation, alors lisez la section sur la légalité en fin d'article avant de pointer ceci sur quoi que ce soit de réel. Pour tout usage en production ou commercial, l'API Graph Instagram officielle est le bon outil, pas un scraper.

Ce que vous allez construire

Un petit script Python qui prend une URL de profil Instagram public, récupère la page entièrement rendue via la Crawling API avec un token JavaScript, et en extrait quelques champs publics :

  • Nom d'utilisateur public le handle de compte affiché sur le profil.
  • Légendes de publications publiques le texte visible sur les publications publiques.
  • Comptages publics de likes et de commentaires les nombres agrégés qu'affiche une publication, et non les personnes derrière eux.
  • URLs de publications publiques le lien permanent vers chaque publication publique.

Remarquez ce qui est délibérément absent : pas de listes de followers, pas d'identités des commentateurs, pas de contenu de comptes privés, pas de coordonnées. Ce sont des données personnelles de particuliers, et leur collecte est hors de portée ici intentionnellement.

Pourquoi une simple requête échoue sur Instagram

Interrogez une URL de profil Instagram public avec un client HTTP basique et vous obtiendrez une réponse techniquement réussie et pratiquement inutile. Le corps est une coquille JavaScript : le vrai contenu n'apparaît qu'après l'exécution des scripts de la page dans un navigateur et la récupération des données depuis des points de terminaison internes. En plus de cela, Instagram signale le trafic automatisé rapidement. Les plages d'adresses IP de datacenter, l'absence de comportement de navigateur et les motifs de requêtes répétitifs sont challengés ou limités bien avant que le contenu intéressant ne se charge.

Un scraper Instagram fonctionnel nécessite donc deux choses dans la même requête : un vrai navigateur qui rende la page, et une adresse IP que la plateforme perçoit comme un visiteur ordinaire. Vous pouvez construire cela vous-même avec un navigateur headless et un pool de proxies résidentiels rotatifs, mais maintenir cet ensemble en bon état représente l'essentiel du travail. La Crawling API réunit les deux en un seul appel. Vous lui envoyez une URL avec un token JavaScript, elle rend la page derrière une adresse IP résidentielle de confiance, et vous retourne le HTML complet que vous pouvez analyser. Pour plus de contexte, consultez notre guide sur comment crawler des sites JavaScript.

Pourquoi le token JS

Crawlbase propose deux types de tokens. Le token normal récupère le HTML statique ; le token JavaScript (JS) rend d'abord la page dans un vrai navigateur. Instagram est rendu côté client, vous avez donc besoin du token JS ici. Le token normal renvoie la même coquille qu'une simple requête, sans rien d'utile à en extraire.

Prérequis

Quelques éléments à mettre en place d'abord. Aucun ne prend longtemps.

Python de base. Vous devez être à l'aise pour exécuter un script et installer des paquets avec pip. Si vous débutez dans l'analyse HTML, notre primer sur comment utiliser BeautifulSoup en Python couvre la partie extraction.

Python 3.8 ou version ultérieure. Vérifiez avec python --version. Si vous ne l'avez pas, installez-le depuis python.org.

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 comme un mot de passe : il authentifie vos requêtes, gardez-le hors du contrôle de version.

Configurer le projet

Créez un environnement virtuel isolé, puis installez les deux bibliothèques dont le scraper a besoin.

bash
python --version

python -m venv instagram_env
source instagram_env/bin/activate

pip install crawlbase beautifulsoup4

Sur Windows, activez avec instagram_env\Scripts\activate au lieu de la ligne source. Deux dépendances effectuent le travail : crawlbase est le client officiel de la Crawling API, et beautifulsoup4 analyse le HTML retourné pour que vous puissiez extraire les champs individuels par sélecteur.

Étape 1 : Récupérer le profil rendu

Commencez par obtenir la page complète. Importez CrawlingAPI, initialisez-la avec votre token JS et demandez une URL de profil public. Vérifiez le code de statut avant d'analyser pour que les échecs restent 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__":
    page_url = "https://www.instagram.com/nasa/"
    html = crawl(page_url)
    print(html[:500] if html else "No HTML returned")

Les deux options d'attente sont importantes pour une cible rendue côté client. ajax_wait indique à l'API d'attendre que le contenu asynchrone ait fini de se charger, et page_wait maintient un délai fixe en millisecondes après le chargement pour que les éléments à rendu tardif apparaissent avant la capture de la page. Cinq secondes est un point de départ raisonnable ; augmentez si des champs reviennent vides. L'exemple utilise un compte d'organisation public (NASA) précisément parce qu'il est public et impersonnel. Exécutez le script et vous devriez voir le vrai balisage du profil, ce qui confirme que le rendu fonctionne avant d'écrire le moindre sélecteur.

Crawlbase Crawling API

Instagram nécessite une page rendue derrière une adresse IP de confiance, en un seul appel. La Crawling API prend un token JS, exécute la page dans un vrai navigateur, fait tourner des adresses IP résidentielles côté serveur et vous livre le HTML complet, vous évitant ainsi de gérer vous-même une flotte headless et un pool de proxies. Pointez-la vers un profil public sur le niveau gratuit en premier.

Étape 2 : Analyser les champs publics avec BeautifulSoup

Avec le HTML rendu en main, chargez-le dans BeautifulSoup et extrayez les champs publics. Instagram expose de nombreuses métadonnées utiles dans les balises <meta> de la page et dans un bloc JSON-LD intégré, ce qui est plus stable que de suivre des classes CSS profondément imbriquées et fréquemment renommées. Le nom d'utilisateur et la description du profil se trouvent dans les méta-balises standard ; les liens permanents de publication se trouvent dans les hrefs d'ancres qui suivent le motif /p/<shortcode>/.

python
import re
from bs4 import BeautifulSoup

def meta(soup, prop):
    el = soup.find("meta", attrs={"property": prop})
    return el["content"] if el and el.has_attr("content") else None

def scrape_profile(html):
    soup = BeautifulSoup(html, "html.parser")

    username = meta(soup, "og:title")
    summary = meta(soup, "og:description")

    post_urls = []
    for a in soup.select("a[href^='/p/']"):
        href = a["href"]
        url = f"https://www.instagram.com{href}"
        if url not in post_urls:
            post_urls.append(url)

    return {
        "username": username,
        "summary": summary,
        "post_urls": post_urls,
    }

La balise og:description sur un profil public contient généralement les comptages agrégés publics (followers, following, publications) sous forme de chaîne de résumé unique. Traitez-les comme de simples agrégats publics uniquement, jamais comme une porte d'entrée pour énumérer les personnes qui se cachent derrière. Les URLs de publications sont collectées depuis les ancres et dédupliquées, car le même lien permanent peut apparaître plus d'une fois dans le DOM rendu.

Les sélecteurs évoluent

Instagram change son balisage et ses noms de classe sans préavis, c'est pourquoi ce code s'appuie sur les méta-balises et la forme d'URL stable /p/<shortcode>/ plutôt que sur des classes imbriquées fragiles. Quand un champ revient comme None, inspectez à nouveau la page en direct dans les outils de développement de votre navigateur et mettez à jour le sélecteur. Une maintenance périodique est normale pour tout scraper en production, ce n'est pas le signe que quelque chose est cassé.

Étape 3 : Extraire les champs publics d'une publication individuelle

Une page de publication publique contient le même type de données méta et JSON-LD. Vous pouvez en extraire la légende publique et les comptages publics de likes et de commentaires. Instagram intègre un script application/ld+json sur les pages de publication qui contient souvent un bloc interactionStatistic avec ces chiffres agrégés, ainsi que le texte de la légende. L'analyse du JSON-LD est plus durable que le scraping de widgets rendus.

python
import json
from bs4 import BeautifulSoup

def scrape_post(html):
    soup = BeautifulSoup(html, "html.parser")
    block = soup.find("script", attrs={"type": "application/ld+json"})
    if not block:
        return {}

    data = json.loads(block.string)
    likes = comments = None
    for stat in data.get("interactionStatistic", []):
        kind = stat.get("interactionType", "")
        count = stat.get("userInteractionCount")
        if "LikeAction" in kind:
            likes = count
        elif "CommentAction" in kind:
            comments = count

    return {
        "caption": data.get("caption") or data.get("articleBody"),
        "like_count": likes,
        "comment_count": comments,
    }

Ceci extrait uniquement des champs agrégés non personnels : le texte de la légende, le nombre public de likes et le nombre public de commentaires. Il ne lit pas les commentaires individuels, les handles des commentateurs, ni qui a aimé la publication. Cette retenue est intentionnelle, et c'est aussi ce qui rend le travail défendable. Les comptages de likes et de commentaires sont des chiffres ; les personnes derrière eux ne vous appartiennent pas à récolter.

Étape 4 : Assembler le tout

Maintenant, reliez la récupération et l'analyse dans un script exécutable unique qui lit un profil public, puis visite ses premières publications publiques.

python
import json
import time
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 main():
    profile_url = "https://www.instagram.com/nasa/"
    html = crawl(profile_url)
    if not html:
        return

    profile = scrape_profile(html)
    records = []
    for post_url in profile["post_urls"][:5]:
        post_html = crawl(post_url)
        if post_html:
            record = scrape_post(post_html)
            record["url"] = post_url
            records.append(record)
        time.sleep(3)

    output = {"username": profile["username"], "posts": records}
    print(json.dumps(output, indent=2, ensure_ascii=False))

if __name__ == "__main__":
    main()

Le time.sleep(3) entre les requêtes n'est pas une décoration. Le cadencement est le facteur unique le plus important pour qu'un run reste en bonne santé, et nous y reviendrons. Le slice [:5] garde la démo petite ; augmentez-le seulement quand votre cadencement et votre volume sont responsables.

À quoi ressemble le résultat

Exécutez le script complet et vous obtenez un enregistrement propre de champs publics, prêt à écrire en JSON, CSV ou dans une base de données.

json
{
  "username": "NASA (@nasa)",
  "posts": [
    {
      "caption": "A new view of a distant galaxy cluster.",
      "like_count": 412338,
      "comment_count": 1894,
      "url": "https://www.instagram.com/p/Cxample123/"
    }
  ]
}

Rester débloqué

Même avec le rendu géré par la Crawling API, Instagram surveille le trafic ayant l'apparence d'un scraper. Quelques habitudes permettent de maintenir un run en bonne santé, et elles s'appliquent à toute cible durement défendue.

  • Cadencez vos requêtes. Bombarder des pages dans une boucle serrée est le moyen le plus rapide d'être limité. Ajoutez de vrais délais, comme dans le time.sleep ci-dessus, et résistez à l'envie de paralléliser agressivement.
  • 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 construisez votre propre infrastructure, c'est la partie à soigner. Notre guide sur comment utiliser des proxies rotatifs va plus loin.
  • Lisez les codes de statut. Un run qui commence à renvoyer des challenges ou des erreurs vous indique que le débit ou le niveau d'adresses IP actuel n'est plus suffisant. Ralentissez plutôt que de pousser davantage.
  • Maintenez un faible volume et variez les cibles. La recherche sur les données publiques ne nécessite pas de crawler l'intégralité de l'historique d'un compte. Prélevez ce dont vous avez besoin et arrêtez-vous.

Pour un guide plus complet, consultez comment contourner les captchas lors du web scraping et notre analyse approfondie sur comment scraper des pages JavaScript avec Python. Si vous préférez router votre propre trafic via un pool rotatif plutôt que d'utiliser l'API gérée, le Smart AI Proxy vous donne la même rotation résidentielle comme point de terminaison proxy.

Est-il légal de scraper Instagram ?

C'est la section à lire avant d'écrire du code de production. Instagram appartient à Meta, et les conditions d'utilisation de Meta restreignent fortement l'accès automatisé et la collecte de données. Le scraping automatisé peut aller à l'encontre de ces conditions, quelle que soit la prudence de vos outils, et aucun code ci-dessus ne change cela. Il se contente de faire fonctionner la partie technique. Lisez les conditions d'utilisation de Meta et d'Instagram ainsi que le robots.txt d'Instagram, et traitez les deux comme la limite de ce que vous collectez.

Les règles honnêtes et restrictives à respecter. Collectez uniquement des données publiques de comptes publics : champs de profil publics, légendes de publications publiques, comptages publics de likes et de commentaires, et URLs de publications publiques que n'importe qui peut voir sans se connecter. Ne scrappez jamais les comptes privés, le contenu protégé par une connexion, les messages directs, les listes de followers ou de following, les identités des commentateurs ou des personnes ayant aimé les publications individuelles, ni aucune donnée personnelle de personnes individuelles. Ne contournez jamais l'authentification, ne résolvez pas un challenge de connexion de manière programmatique, ni n'utilisez les identifiants de quelqu'un d'autre pour accéder à du contenu. Ce sont des lignes claires, et ce guide reste délibérément du côté public de toutes ces lignes.

Pour tout usage réel ou commercial, le bon outil est l'API Graph Instagram officielle. Elle est conçue pour un accès sanctionné aux comptes que vous possédez ou gérez, vous donne une structure garantie et vous maintient dans les conditions de Meta. Cet article est un tutoriel technique limité strictement aux données publiques de comptes publics. Ce n'est pas une approbation de la collecte massive de données personnelles, et il ne couvre pas ce qui se trouve derrière une connexion. Si votre projet nécessite plus qu'un petit échantillon de champs publics, l'API Graph ou un accord de données formel est la bonne voie, pas un scraper plus sophistiqué.

Récapitulatif

Points clés

  • Instagram est rendu côté client et défendu contre les bots. Une simple requête renvoie une coquille vide, vous devez donc rendre la page avant de l'analyser.
  • Le rendu et une adresse IP de confiance appartiennent au même appel. La Crawling API avec un token JS fait les deux ; ajax_wait et page_wait contrôlent la durée d'attente du contenu.
  • Analysez des signaux stables. Les méta-balises, la forme d'URL /p/<shortcode>/ et le JSON-LD sont plus durables que les classes imbriquées fragiles.
  • Uniquement des agrégats publics. Extrayez le nom d'utilisateur, les légendes, les comptages de likes et de commentaires, et les URLs de publications ; jamais les listes de followers, les identités des commentateurs, ni le contenu privé.
  • Cadencez, faites tourner et préférez l'API Graph. Maintenez un faible volume, misez sur la rotation résidentielle et utilisez l'API Graph Instagram officielle pour tout usage réel ou commercial.

Foire aux questions

Pourquoi une simple requête ne renvoie-t-elle pas de données d'Instagram ?

Parce qu'Instagram rend son contenu de profil et de publication côté client en JavaScript. Le HTML initial est une coquille qui ne se remplit qu'après l'exécution des scripts de la page dans un navigateur, donc une requête HTTP brute renvoie un corps presque vide. Pour obtenir de vraies données publiques, vous devez d'abord rendre la page, ce que gère le token JS de la Crawling API.

Ai-je besoin du token normal ou du token JS pour Instagram ?

Le token JS. Le token normal récupère le HTML statique, qui sur Instagram est la même coquille vide qu'une simple requête. Le token JS rend la page dans un vrai navigateur avant de retourner le HTML, de sorte que les champs publics sont présents quand BeautifulSoup les analyse.

Quelles données Instagram peut-on scraper en toute sécurité ?

Uniquement les données publiques de comptes publics : le nom d'utilisateur public, les légendes de publications publiques, les comptages publics de likes et de commentaires en tant que nombres agrégés, et les URLs de publications publiques. Les comptes privés, le contenu protégé par une connexion, les messages directs, les listes de followers et de following, et les identités des commentateurs ou des personnes ayant aimé les publications individuelles sont hors limites. Ce sont des données personnelles, et leur collecte va à l'encontre des conditions de Meta et, dans de nombreux endroits, de la législation sur la vie privée.

Dois-je utiliser l'API Graph Instagram officielle ou scraper le site ?

Pour tout usage réel, continu ou commercial, utilisez l'API Graph Instagram officielle. C'est la voie sanctionnée, elle offre une structure garantie et vous maintient dans les conditions de Meta. Scraper un petit échantillon de champs publics avec cette approche convient à la recherche légère sur les données publiques où aucun accès API n'est en place, tant que vous respectez les conditions, le robots.txt et les limites de débit.

Comment éviter d'être bloqué lors du scraping d'Instagram ?

Maintenez votre taux de requêtes par adresse IP bas, ajoutez de vrais délais entre les requêtes, variez vos cibles au lieu de crawler l'intégralité de l'historique d'un compte et routez via des adresses IP résidentielles rotatives pour qu'aucune adresse individuelle ne déclenche une limite de débit. La Crawling API gère la rotation et un pool d'adresses IP de confiance pour vous. Surveillez les codes de statut et ralentissez dès que vous commencez à voir des challenges.

Puis-je scraper des comptes privés ou des listes de followers ?

Non, et ce guide ne montre délibérément pas comment. Le contenu des comptes privés se trouve derrière l'authentification, et les listes de followers et les identités d'utilisateurs individuels sont des données personnelles. Scraper du contenu protégé par une connexion, énumérer les followers ou contourner l'authentification pour y accéder est hors de portée ici et va à l'encontre des conditions de Meta. Pour un accès sanctionné aux comptes que vous possédez ou gérez, l'API Graph Instagram officielle est la bonne voie.

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