GitHub est l'un des ensembles de données publiques les plus riches en matière de logiciels. Les pages de dépôts publics portent le nom d'un projet, sa description, le nombre d'étoiles et de forks, le langage principal et les sujets, tandis que les pages de profil public résument le nom public d'un développeur, sa bio, le nombre de dépôts publics et le nombre de followers. Ces données alimentent de nombreux travaux légitimes : suivre la popularité des projets open source, étudier quels langages et frameworks gagnent en traction, et construire des tableaux de bord des bibliothèques dont dépend une équipe.

Ce guide vous montre comment extraire des données de dépôts et profils GitHub publics avec Python via la Crawling API de Crawlbase, analyser les champs pertinents et les exporter en JSON et CSV. Tout ici est limité aux pages publiques que n'importe qui peut ouvrir sans se connecter. Il ne touche pas aux dépôts privés, aux listes de membres d'organisations, aux adresses e-mail ni à quoi que ce soit derrière une authentification. Lisez la section légalité vers la fin avant de pointer ce script sur quoi que ce soit de réel, et notez dès le départ que GitHub propose une API REST officielle qui est le meilleur outil pour la plupart de ces tâches.

Ce que vous allez construire

Un petit script Python qui prend une URL publique de dépôt ou de profil GitHub, récupère la page via la Crawling API, l'analyse avec BeautifulSoup et écrit des enregistrements structurés en JSON et CSV. Les champs extraits :

  • Nom du dépôt le nom du projet affiché dans l'en-tête du dépôt.
  • Description le résumé en une ligne dans la barre latérale.
  • Étoiles le nombre public d'étoiles.
  • Forks le nombre public de forks.
  • Watchers le nombre d'utilisateurs suivant le dépôt.
  • Langage et sujets le langage principal et les tags de sujets du dépôt.
  • Champs de profil pour une URL d'utilisateur : nom public, bio, nombre de dépôts publics et nombre de followers.

Remarquez ce qui est délibérément absent : pas d'adresses e-mail, pas de dépôts privés, pas de listes de membres d'organisations privées, et aucune tentative de constituer un dossier sur un individu. Les données de profil décrivent de vraies personnes, le script les traite donc comme des données personnelles et se limite aux champs publics grossiers.

Pourquoi une requête simple peut échouer sur GitHub

GitHub sert la plupart de son contenu de dépôt et de profil en HTML rendu côté serveur, une requête simple retourne donc souvent un balisage utilisable. La friction apparaît en volume. GitHub limite agressivement le trafic non authentifié, et une boucle serrée depuis une seule IP de centre de données est rapidement limitée ou soumise à un défi. La navigation anonyme vous donne également une page moins complète qu'une session connectée, et le balisage change entre les vues connectées et déconnectées, ce qui casse les sélecteurs fragiles.

Un scraper GitHub fiable a donc besoin de requêtes qui semblent provenir de visiteurs ordinaires et se répartissent sur de nombreuses adresses IP pour qu'aucune ne dépasse une limite. Vous pouvez construire cela vous-même avec un pool de proxies rotatifs et votre propre logique de relance, mais maintenir cette pile en bon état représente l'essentiel du travail. La Crawling API réduit tout à un seul appel : vous envoyez une URL, elle récupère la page derrière une IP de confiance et rotative, et renvoie le HTML complet à analyser. Les pages GitHub sont suffisamment statiques pour que le token normal soit le bon choix ici, sans rendu JavaScript nécessaire.

Quel token

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. Les pages de dépôts et de profils GitHub sont rendues côté serveur, le token normal est donc suffisant et coûte moins cher. Optez pour le token JS uniquement si une page spécifique dont vous avez besoin dépend du rendu côté client.

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 l'analyse HTML est nouvelle pour vous, notre guide sur l'utilisation de BeautifulSoup en Python couvre le côté extraction, et extraire des données d'un site avec Python présente le flux complet.

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

Un compte Crawlbase et un token. Inscrivez-vous, ouvrez votre tableau de bord et copiez votre token normal depuis la page de documentation du compte. Crawlbase inclut jusqu'à 20 000 requêtes gratuites pour commencer, et vous ne payez que pour les requêtes réussies. Traitez le token comme un mot de passe : gardez-le hors du contrôle de version.

Configurer le projet

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

bash
python --version

python -m venv github_env
source github_env/bin/activate

pip install crawlbase beautifulsoup4 pandas

Sur Windows, activez avec github_env\Scripts\activate à la place de la ligne source. Trois dépendances font le travail : crawlbase est le client officiel pour la Crawling API, beautifulsoup4 analyse le HTML renvoyé pour extraire les champs par sélecteur, et pandas transforme les enregistrements en CSV à la fin.

Étape 1 : récupérer une page de dépôt public

Commencez par obtenir la page complète. Importez CrawlingAPI, initialisez-la avec votre token et demandez une URL de dépôt 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_TOKEN"})

def crawl(page_url):
    response = api.get(page_url)
    if response["status_code"] == 200:
        return response["body"].decode("latin1")
    print(f"Request failed: {response['status_code']}")
    return None

if __name__ == "__main__":
    page_url = "https://github.com/TheAlgorithms/Java"
    html = crawl(page_url)
    print(html[:500] if html else "No HTML returned")

Le corps est décodé en latin1 pour éviter les erreurs sur les octets non-UTF-8 occasionnels dans le HTML rendu d'un dépôt. L'exemple pointe vers un dépôt public bien connu pour que vous puissiez confirmer que la récupération fonctionne avant d'écrire le moindre sélecteur. Exécutez-le et vous devriez voir le vrai balisage GitHub dans les 500 premiers caractères, ce qui confirme que la requête a atteint la page derrière une IP de confiance.

Crawlbase GitHub Scraper

L'appel api.get ci-dessus fait plus qu'une simple requête HTTP. GitHub limite le trafic non authentifié et une seule IP de centre de données se trouve rapidement limitée, la Crawling API récupère donc chaque page derrière une IP résidentielle rotative et gère les relances et les CAPTCHA pour vous. Vous évitez de gérer un pool de proxies et la logique de back-off qui va avec. Pointez-la sur un dépôt public depuis le niveau gratuit d'abord.

Étape 2 : analyser les champs du dépôt

Avec le HTML rendu en main, chargez-le dans BeautifulSoup et extrayez les champs du dépôt. L'en-tête de dépôt de GitHub expose le nom via un attribut itemprop, la description se trouve dans la barre latérale, et les nombres d'étoiles, de forks et de watchers se trouvent à côté de leurs icônes SVG Octicon, ce qui fait de ces icônes des ancres fiables pour les chiffres à côté d'elles. Les sujets sont des liens tagués, et le langage principal apparaît dans la liste des langages.

python
from bs4 import BeautifulSoup

def text_of(soup, selector):
    el = soup.select_one(selector)
    return el.text.strip() if el else None

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

    topics = [t.text.strip() for t in
              soup.select('a[data-octo-click="topic_click"]')]

    return {
        "name": text_of(soup,
            'strong[itemprop="name"] a'),
        "description": text_of(soup,
            "div.Layout-sidebar div.BorderGrid-row p.f4.my-3"),
        "stars": text_of(soup,
            "svg.octicon-star ~ strong"),
        "forks": text_of(soup,
            "svg.octicon-repo-forked ~ strong"),
        "watchers": text_of(soup,
            "svg.octicon-eye ~ strong"),
        "language": text_of(soup,
            'span[itemprop="programmingLanguage"]'),
        "topics": topics,
    }

L'assistant text_of renvoie None quand un sélecteur rate, un champ absent ne fait donc jamais planter l'analyse complète. Les sélecteurs d'étoiles, de forks et de watchers utilisent la classe de l'icône Octicon comme ancre et un combinateur de frères (~ strong) pour saisir le nombre rendu à côté, ce qui est plus robuste que de dépendre d'une chaîne de classes profondément imbriquées. Les sujets sont collectés depuis chaque lien topic_click dans une liste.

Les sélecteurs évoluent

GitHub révise périodiquement son balisage, un sélecteur qui fonctionne aujourd'hui peut donc renvoyer None plus tard. Quand un champ revient vide, ouvrez la page en direct dans les outils de développement de votre navigateur et mettez à jour le sélecteur. S'ancrer sur des hooks stables comme itemprop et les classes d'icônes Octicon plutôt que sur des classes utilitaires auto-générées réduit la maintenance au minimum.

Étape 3 : analyser une page de profil public

Une page de profil public porte un ensemble différent de champs. Vous pouvez en extraire le nom d'affichage public de l'utilisateur, son pseudonyme (le handle), la bio, le nombre de dépôts publics et le nombre de followers. GitHub marque le nom d'affichage et le pseudonyme avec des classes vcard stables, et le nombre de dépôts et le nombre de followers se trouvent à côté de leurs propres icônes Octicon, le même schéma que la page de dépôt.

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

    return {
        "name": text_of(soup,
            "span.p-name.vcard-fullname"),
        "username": text_of(soup,
            "span.p-nickname.vcard-username"),
        "bio": text_of(soup,
            "div.p-note.user-profile-bio div"),
        "repositories": text_of(soup,
            "svg.octicon-repo ~ span"),
        "followers": text_of(soup,
            "svg.octicon-people ~ span.color-fg-default"),
    }

Ce sont les champs publics grossiers qu'un profil montre à tout visiteur déconnecté. Le script s'arrête délibérément là. Il ne lit pas l'e-mail d'un utilisateur, ses appartenances à des organisations ni le contenu de ses dépôts, et il n'assemble pas de profils pour constituer un dossier sur une personne. Le nom public, la bio, le nombre de dépôts et le nombre de followers sont des signaux agrégés sur l'empreinte publique d'un développeur ; la personne derrière eux n'est pas à vous de profiler.

Étape 4 : assembler et exporter

Reliez maintenant récupération et analyse en un script exécutable unique qui lit un dépôt et un profil, puis écrit en JSON et CSV avec pandas.

python
import json
import time
import pandas as pd
from crawlbase import CrawlingAPI
from bs4 import BeautifulSoup

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"})

def crawl(page_url):
    response = api.get(page_url)
    if response["status_code"] == 200:
        return response["body"].decode("latin1")
    print(f"Request failed: {response['status_code']}")
    return None

def main():
    repo_url = "https://github.com/TheAlgorithms/Java"
    profile_url = "https://github.com/torvalds"

    records = []

    repo_html = crawl(repo_url)
    if repo_html:
        repo = scrape_repository(repo_html)
        repo["url"] = repo_url
        records.append(repo)
    time.sleep(3)

    profile_html = crawl(profile_url)
    if profile_html:
        profile = scrape_profile(profile_html)
        profile["url"] = profile_url
        records.append(profile)

    with open("github_data.json", "w") as f:
        json.dump(records, f, indent=2, ensure_ascii=False)

    pd.DataFrame(records).to_csv("github_data.csv", index=False)
    print(f"Wrote {len(records)} records to JSON and CSV")

if __name__ == "__main__":
    main()

Le time.sleep(3) entre les requêtes n'est pas décoratif. La cadence est le facteur le plus important pour qu'une exécution reste saine sur une cible à débit limité comme GitHub. Le script collecte un enregistrement de dépôt et un enregistrement de profil dans une seule liste, écrit le résultat structuré dans github_data.json et laisse pandas aplatir les mêmes enregistrements dans github_data.csv pour un tableur. La liste topics se sérialise proprement en JSON et atterrit comme une chaîne dans la colonne CSV.

À quoi ressemble le résultat

Exécutez le script complet et vous obtenez un enregistrement propre de champs publics, prêt à charger dans un notebook, une base de données ou un tableur.

json
[
  {
    "name": "Java",
    "description": "All Algorithms implemented in Java",
    "stars": "59.1k",
    "forks": "19.5k",
    "watchers": "1.3k",
    "language": "Java",
    "topics": ["algorithms", "java", "data-structures"],
    "url": "https://github.com/TheAlgorithms/Java"
  },
  {
    "name": "Linus Torvalds",
    "username": "torvalds",
    "bio": null,
    "repositories": "8",
    "followers": "219k",
    "url": "https://github.com/torvalds"
  }
]

Le formatage exact des étoiles et des followers (59.1k, 219k) provient directement des compteurs rendus par GitHub. Si vous avez besoin d'entiers bruts, la valeur précise se trouve généralement dans l'attribut title de l'élément ; lisez-le à la place du texte visible quand vous avez besoin de faire des calculs sur les chiffres.

Passer à l'échelle sur de nombreux dépôts

Le script sur une seule page se généralise facilement. Pour étudier un ensemble de projets, conservez une liste d'URLs de dépôts et faites tourner le même appel scrape_repository dessus, en accumulant les enregistrements avant d'exporter une seule fois à la fin.

python
repo_urls = [
    "https://github.com/TheAlgorithms/Java",
    "https://github.com/pallets/flask",
    "https://github.com/psf/requests",
]

records = []
for url in repo_urls:
    html = crawl(url)
    if html:
        record = scrape_repository(html)
        record["url"] = url
        records.append(record)
    time.sleep(3)

Maintenez le délai entre les requêtes, surveillez les codes de statut et arrêtez-vous quand vous avez ce dont vous avez besoin plutôt que de crawler de façon exhaustive. Pour le guide général sur la santé contre les limites de débit, voir comment extraire des données sans être bloqué. 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 offre la même rotation résidentielle comme endpoint proxy de substitution, et notre récapitulatif des meilleures bibliothèques de scraping open source couvre les choix de parseurs et de crawlers si vous souhaitez assembler votre propre pile.

Est-il légal d'extraire des données de GitHub ?

C'est la section à lire avant d'écrire du code de production. Le scraping de pages GitHub publiques à des fins personnelles ou éducatives est généralement défendable, car les données sont publiées pour que quiconque puisse les lire sans se connecter. Cela ne le rend pas inconditionnel. Les Politiques d'utilisation acceptable de GitHub régissent l'accès automatisé, et son fichier robots.txt indique aux crawlers quels chemins sont interdits. Lisez les deux et traitez-les comme la limite. Ne touchez jamais aux dépôts privés, au contenu protégé par connexion, ni à quoi que ce soit pour lequel vous auriez besoin de credentials, et ne frappez pas le site à un débit qui le dégrade pour les autres.

Les données de profil méritent une attention particulière, car elles décrivent de vraies personnes. Un nom public, une bio et un nombre de followers sont des données personnelles, et dans de nombreuses juridictions les lois sur la vie privée comme le RGPD et le CCPA s'appliquent dès que vous collectez et stockez des informations sur des individus identifiables, même quand ces informations sont publiques. Cela signifie avoir une base juridique pour ce que vous collectez, ne garder que ce dont vous avez besoin, et honorer les demandes de suppression. Agrégez quand vous le pouvez (comptages et tendances sur de nombreux dépôts) plutôt que de constituer des dossiers sur des développeurs nommés, et ne republiez jamais les détails d'un individu ni n'assemblez son empreinte en un profil de la personne.

Pour la plupart des tâches, le meilleur outil est l'API REST officielle de GitHub. Elle est généreuse, gratuite pour un usage normal, et vous donne du JSON propre et structuré pour les dépôts, utilisateurs, étoiles, forks, langages et sujets sans analyser le moindre HTML. C'est la voie sanctionnée, elle résiste aux changements de balisage, et elle vient avec des limites de débit documentées sur lesquelles vous pouvez planifier. Recourez au scraping uniquement quand une page publique spécifique contient quelque chose que l'API n'expose pas, et gardez ce travail petit, cadencé et limité aux champs publics non sensibles. Si votre projet a besoin de données GitHub à une échelle réelle, commencez par l'API REST, pas un scraper.

Récapitulatif

Points clés

  • GitHub est rendu côté serveur mais à débit limité. Une simple requête retourne le balisage, mais le trafic non authentifié depuis une seule IP est rapidement limité, routez donc les requêtes via des IPs rotatives.
  • Le token normal est suffisant. Les pages de dépôts et de profils ne nécessitent pas de rendu JavaScript, le token normal moins cher récupère donc tout ce dont vous avez besoin.
  • Ancrez-vous sur des hooks stables. Analysez les champs de dépôt via les attributs itemprop et les classes d'icônes Octicon, et les champs de profil via les classes vcard, pas les classes utilitaires auto-générées.
  • Traitez les données de profil comme des données personnelles. Extrayez des champs publics grossiers, agrégez plutôt que de profiler des individus, et respectez le RGPD et le CCPA quand vous les stockez.
  • Préférez l'API REST de GitHub. Elle est gratuite, généreuse et structurée ; ne scrapez que les pages publiques qu'elle ne couvre pas, de façon cadencée et en petite quantité.

Foire aux questions

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

Le token normal. GitHub rend les pages de dépôts et de profils côté serveur, le HTML statique contient donc déjà le nom, la description, le nombre d'étoiles et de forks, le langage, les sujets et les champs de profil public. Le token JS rend d'abord les pages dans un navigateur et coûte plus cher, ce que vous ne nécessitez que pour la rare vue GitHub qui dépend du rendu côté client.

Quelles données GitHub est-il sûr d'extraire ?

Les données publiques que tout visiteur déconnecté peut voir : le nom, la description, les étoiles, les forks, les watchers, le langage principal et les sujets d'un dépôt public, ainsi que le nom, la bio, le nombre de dépôts publics et le nombre de followers d'un profil public. Les dépôts privés, les listes de membres d'organisations, les adresses e-mail et tout ce qui est derrière une authentification sont hors limites, à la fois selon les conditions de GitHub et, pour les données personnelles, selon la loi sur la vie privée.

Devrais-je utiliser l'API REST de GitHub plutôt que de scraper ?

Pour la plupart des tâches, oui. L'API REST officielle de GitHub est gratuite pour un usage normal, généreuse avec ses limites de débit, et renvoie du JSON propre pour les dépôts, utilisateurs, étoiles, forks, langages et sujets sans analyser le HTML. C'est la voie sanctionnée et elle résiste aux changements de balisage. Recourez au scraping uniquement quand une page publique spécifique expose quelque chose que l'API n'expose pas, et gardez ce travail petit et cadencé.

Comment éviter d'être limité en débit lors du scraping de GitHub ?

Maintenez un faible débit de requêtes par IP, ajoutez de vrais délais entre les requêtes comme dans le time.sleep(3) ci-dessus, et routez via des IPs résidentielles rotatives pour qu'aucune adresse unique ne déclenche une limite. La Crawling API gère la rotation et les relances pour vous. Surveillez les codes de statut et ralentissez dès que vous commencez à voir des défis ou des erreurs plutôt que d'insister.

Pourquoi les compteurs d'étoiles et de followers sont-ils des chaînes comme "59.1k" ?

Parce que c'est le texte abrégé que GitHub rend sur la page, et le script lit le texte visible. Quand vous avez besoin d'entiers exacts, regardez l'attribut title de l'élément, qui contient généralement le nombre précis, et lisez-le à la place du texte affiché avant de faire des calculs.

Puis-je scraper des dépôts privés ou des adresses e-mail d'utilisateurs ?

Non, et ce guide ne montre délibérément pas comment. Les dépôts privés sont derrière une authentification, et les adresses e-mail sont des données personnelles que GitHub n'expose pas aux visiteurs anonymes. Atteindre l'un ou l'autre signifierait contourner des contrôles d'accès ou collecter des données personnelles sans base juridique, deux actions contraires aux conditions de GitHub et à la loi sur la vie privée. Pour accéder aux comptes ou organisations que vous contrôlez, authentifiez-vous via l'API REST officielle de GitHub.

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