GitHub ist einer der reichhaltigsten öffentlichen Datensätze in der Softwareentwicklung. Öffentliche Repository-Seiten enthalten den Projektnamen, die Beschreibung, die Anzahl von Stars und Forks, die primäre Programmiersprache und Topics, während öffentliche Profilseiten den öffentlichen Namen eines Entwicklers, seine Bio, die Anzahl der öffentlichen Repositories und die Follower-Anzahl zusammenfassen. Diese Daten dienen vielen legitimen Zwecken: die Popularität von Open-Source-Projekten verfolgen, ermitteln, welche Sprachen und Frameworks an Bedeutung gewinnen, und Dashboards der Bibliotheken erstellen, von denen ein Team abhängt.
Diese Anleitung zeigt, wie man öffentliche GitHub-Repositories und -Profile mit Python über die Crawlbase Crawling API scrapt, die relevanten Felder parst und in JSON und CSV exportiert. Alles hier beschränkt sich auf öffentliche Seiten, die jeder ohne Login öffnen kann. Private Repositories, Organisationsmitgliederlisten, E-Mail-Adressen oder alles hinter einer Authentifizierung werden nicht berührt. Lesen Sie den Abschnitt zur Rechtslage am Ende, bevor Sie diesen Ansatz in der Praxis anwenden, und beachten Sie von vornherein, dass GitHub eine offizielle REST API anbietet, die für die meisten dieser Aufgaben das bessere Werkzeug ist.
Was Sie erstellen werden
Ein kleines Python-Skript, das eine öffentliche GitHub-Repository- oder Profil-URL entgegennimmt, die Seite über die Crawling API abruft, mit BeautifulSoup parst und strukturierte Datensätze in JSON und CSV schreibt. Folgende Felder werden extrahiert:
- Repository name der im Repository-Header angezeigte Projektname.
- Description die einzeilige Zusammenfassung in der Seitenleiste.
- Stars die öffentliche Star-Anzahl.
- Forks die öffentliche Fork-Anzahl.
- Watchers die Anzahl der Nutzer, die das Repository beobachten.
- Language and topics die primäre Sprache und die Topic-Tags des Repositories.
- Profile fields bei einer Nutzer-URL: öffentlicher Name, Bio, Anzahl öffentlicher Repositories und Follower-Anzahl.
Beachten Sie, was bewusst fehlt: keine E-Mail-Adressen, keine privaten Repositories, keine Mitgliederlisten privater Organisationen und kein Versuch, ein Dossier über eine Einzelperson anzulegen. Profildaten beschreiben echte Menschen, daher behandelt das Skript sie als personenbezogene Daten und beschränkt sich auf grobe öffentliche Felder.
Warum eine einfache Anfrage bei GitHub scheitern kann
GitHub liefert den Großteil seiner Repository- und Profilinhalte als serverseitig gerendertes HTML, sodass eine einfache Anfrage oft nutzbares Markup zurückgibt. Die Probleme treten bei größerem Volumen auf. GitHub drosselt nicht authentifizierten Traffic aggressiv, und eine enge Schleife von einer einzelnen Datacenter-IP wird schnell gedrosselt oder mit einer Challenge konfrontiert. Anonymes Browsen liefert zudem eine schlankere Seite als eine eingeloggte Sitzung, und das Markup unterscheidet sich zwischen eingeloggter und ausgeloggter Ansicht, was fragile Selektoren bricht.
Ein zuverlässiger GitHub-Scraper benötigt daher Anfragen, die wie gewöhnliche Besucher aussehen und über viele IP-Adressen verteilt sind, damit keine einzelne ein Limit auslöst. Sie können das selbst mit einem Pool von rotierenden Proxys und eigenem Retry-Logik aufbauen, doch diesen Stack gesund zu halten ist der Großteil der Arbeit. Die Crawling API fasst das in einem Aufruf zusammen: Sie senden eine URL, sie ruft die Seite hinter einer vertrauenswürdigen, rotierenden IP ab und gibt fertiges HTML zurück, das Sie parsen können. GitHub-Seiten sind statisch genug, dass das normale Token hier die richtige Wahl ist, ohne JavaScript-Rendering.
Crawlbase bietet zwei Token-Typen an. Das normale Token ruft statisches HTML ab; das JavaScript (JS)-Token rendert die Seite zuerst in einem echten Browser. GitHub-Repository- und Profilseiten werden serverseitig gerendert, daher reicht das normale Token aus und kostet weniger. Greifen Sie auf das JS-Token zurück, wenn eine bestimmte Seite, die Sie benötigen, clientseitiges Rendering voraussetzt.
Voraussetzungen
Einige Dinge sollten zunächst vorhanden sein. Keines davon nimmt lange.
Python-Grundkenntnisse. Sie sollten in der Lage sein, ein Skript auszuführen und Pakete mit pip zu installieren. Falls HTML-Parsing neu für Sie ist, erklärt unser Primer zu BeautifulSoup in Python die Extraktionsseite, und eine Website mit Python scrapen zeigt den End-to-End-Ablauf.
Python 3.8 oder neuer. Prüfen Sie Ihre Version mit python --version. Falls Sie sie nicht haben, installieren Sie sie von python.org.
Ein Crawlbase-Konto und Token. Registrieren Sie sich, öffnen Sie Ihr Dashboard und kopieren Sie Ihr normales Token von der Account-Dokumentationsseite. Crawlbase enthält bis zu 20.000 kostenlose Anfragen zum Einstieg, und Sie zahlen nur für erfolgreiche Anfragen. Behandeln Sie das Token wie ein Passwort: halten Sie es aus der Versionskontrolle fern.
Das Projekt einrichten
Erstellen Sie eine isolierte virtuelle Umgebung und installieren Sie dann die drei Bibliotheken, die der Scraper benötigt.
python --version python -m venv github_env source github_env/bin/activate pip install crawlbase beautifulsoup4 pandas
Unter Windows aktivieren Sie die Umgebung mit github_env\Scripts\activate statt der source-Zeile. Drei Abhängigkeiten erledigen die Arbeit: crawlbase ist der offizielle Client für die Crawling API, beautifulsoup4 parst das zurückgegebene HTML, sodass Sie Felder per Selektor extrahieren können, und pandas wandelt die Datensätze am Ende in eine CSV um.
Schritt 1: Eine öffentliche Repository-Seite abrufen
Beginnen Sie damit, die fertige Seite zu laden. Importieren Sie CrawlingAPI, initialisieren Sie sie mit Ihrem Token und rufen Sie eine öffentliche Repository-URL ab. Prüfen Sie den Statuscode vor dem Parsen, damit Fehler laut statt lautlos scheitern.
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")
Der Body wird als latin1 dekodiert, um beim gelegentlichen Nicht-UTF-8-Byte im gerenderten HTML eines Repositories nicht abzubrechen. Das Beispiel verweist auf ein bekanntes öffentliches Repository, damit Sie den Abruf bestätigen können, bevor Sie einen einzigen Selektor schreiben. Führen Sie es aus, und Sie sollten echtes GitHub-Markup in den ersten 500 Zeichen sehen, was bestätigt, dass die Anfrage die Seite hinter einer vertrauenswürdigen IP erreicht hat.
Der obige api.get-Aufruf tut mehr als eine HTTP-Anfrage. GitHub drosselt nicht authentifizierten Traffic, und eine einzelne Datacenter-IP wird schnell limitiert, daher ruft die Crawling API jede Seite hinter einer rotierenden Residential-IP ab und übernimmt Retries und CAPTCHAs für Sie. Sie überspringen den Betrieb eines Proxy-Pools und der zugehörigen Backoff-Logik. Probieren Sie es zunächst mit einem öffentlichen Repository im kostenlosen Tarif aus.
Schritt 2: Die Repository-Felder parsen
Mit dem gerenderten HTML laden Sie es in BeautifulSoup und extrahieren die Repository-Felder. GitHubs Repository-Header stellt den Namen über ein itemprop-Attribut bereit, die Beschreibung befindet sich in der Seitenleiste, und die Star-, Fork- und Watcher-Anzahlen sitzen neben ihren Octicon-SVG-Icons, die zuverlässige Anker für die benachbarten Zahlen sind. Topics sind getaggte Links, und die primäre Sprache erscheint in der Sprachenliste.
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, }
Der text_of-Helfer gibt None zurück, wenn ein Selektor nichts trifft, sodass ein fehlendes Feld nie das gesamte Parsing abbricht. Die Selektoren für Stars, Forks und Watchers verwenden die Octicon-Icon-Klasse als Anker und einen Geschwister-Kombinator (~ strong), um die daneben gerenderte Zahl zu greifen, was robuster ist als das Abhängigsein von einer tief verschachtelten Klassenkette. Topics werden aus jedem topic_click-Link in eine Liste gesammelt.
GitHub überarbeitet sein Markup regelmäßig, sodass ein heute funktionierender Selektor später None zurückgeben kann. Wenn ein Feld leer zurückkommt, öffnen Sie die Live-Seite in den Entwicklertools Ihres Browsers und aktualisieren Sie den Selektor. Die Verwendung stabiler Hooks wie itemprop und der Octicon-Icon-Klassen anstelle von autogenerierten Utility-Klassen minimiert den Wartungsaufwand.
Schritt 3: Eine öffentliche Profilseite parsen
Eine öffentliche Profilseite enthält einen anderen Satz von Feldern. Sie können den öffentlichen Anzeigenamen des Nutzers, seinen Benutzernamen (Handle), die Bio, die Anzahl öffentlicher Repositories und die Follower-Anzahl extrahieren. GitHub kennzeichnet den Anzeigenamen und den Benutzernamen mit stabilen vcard-Klassen, und die Repository- und Follower-Anzahl sitzen neben ihren eigenen Octicon-Icons, dasselbe Muster wie auf der Repository-Seite.
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"), }
Dies sind die groben öffentlichen Felder, die ein Profil jedem ausgeloggten Besucher zeigt. Das Skript endet dort bewusst. Es liest weder die E-Mail eines Nutzers, seine Organisationsmitgliedschaften noch den Inhalt seiner Repositories, und es fügt Profile nicht zu einem Datensatz über eine Person zusammen. Öffentlicher Name, Bio, Repository-Anzahl und Follower-Anzahl sind aggregierte Signale über den öffentlichen Fußabdruck eines Entwicklers; die Person dahinter steht Ihnen nicht zur Profilierung zu.
Schritt 4: Alles zusammenfügen und exportieren
Verbinden Sie nun Abruf und Parsing in einem lauffähigen Skript, das ein Repository und ein Profil liest und dann sowohl JSON als auch CSV mit pandas schreibt.
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()
Das time.sleep(3) zwischen den Anfragen ist kein Dekorationselement. Drosselung ist der wichtigste Einzelfaktor dafür, ob ein Lauf bei einem ratelimitierten Ziel wie GitHub gesund bleibt. Das Skript sammelt einen Repository-Datensatz und einen Profildatensatz in einer Liste, schreibt das strukturierte Ergebnis in github_data.json und lässt pandas dieselben Datensätze in github_data.csv für eine Tabellenkalkulation ausgeben. Die topics-Liste wird sauber nach JSON serialisiert und landet als String in der CSV-Spalte.
Wie die Ausgabe aussieht
Führen Sie das vollständige Skript aus, und Sie erhalten einen sauberen Datensatz öffentlicher Felder, der in ein Notebook, eine Datenbank oder eine Tabellenkalkulation geladen werden kann.
[ { "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" } ]
Die genaue Formatierung von Star- und Follower-Anzahlen (59.1k, 219k) stammt direkt aus GitHubs gerendertem Zählerstand. Wenn Sie rohe Ganzzahlen benötigen, befindet sich der genaue Wert meist im title-Attribut des Elements; lesen Sie dieses statt des sichtbaren Texts, wenn Sie Berechnungen mit den Zahlen anstellen möchten.
Auf viele Repositories skalieren
Das Einzelseiten-Skript lässt sich sauber verallgemeinern. Um eine Reihe von Projekten zu untersuchen, halten Sie eine Liste von Repository-URLs und rufen Sie in einer Schleife denselben scrape_repository-Aufruf auf, akkumulieren Sie Datensätze und exportieren Sie am Ende einmalig.
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)
Halten Sie die Verzögerung zwischen den Anfragen ein, beobachten Sie die Statuscodes und hören Sie auf, sobald Sie das Benötigte haben, statt erschöpfend zu crawlen. Das allgemeine Playbook zum Gesundbleiben gegen Ratelimits finden Sie unter wie man Websites scrapt, ohne geblockt zu werden. Wenn Sie Ihren eigenen Traffic lieber über einen rotierenden Pool leiten möchten statt die verwaltete API zu nutzen, bietet der Smart AI Proxy dieselbe Residential-Rotation als Drop-in-Proxy-Endpunkt, und unser Überblick über die besten Open-Source-Scraping-Bibliotheken behandelt Parser- und Crawler-Optionen, wenn Sie Ihren eigenen Stack zusammenstellen möchten.
Ist es legal, GitHub zu scrapen?
Dies ist der Abschnitt, den Sie lesen sollten, bevor Sie Produktionscode schreiben. Das Scrapen öffentlicher GitHub-Seiten für persönliche oder Bildungszwecke ist generell vertretbar, da die Daten für jeden ohne Login veröffentlicht sind. Das macht es aber nicht bedingungslos. GitHubs Richtlinien zur akzeptablen Nutzung regeln den automatisierten Zugriff, und seine robots.txt teilt Crawlern mit, welche Pfade tabu sind. Lesen Sie beides und betrachten Sie es als Grenze. Berühren Sie niemals private Repositories, login-gesperrte Inhalte oder alles, wofür Sie Anmeldedaten benötigen würden, und hämmern Sie nicht auf die Website mit einer Rate, die sie für andere verlangsamt.
Profildaten verdienen besondere Sorgfalt, da sie echte Menschen beschreiben. Ein öffentlicher Name, eine Bio und eine Follower-Anzahl sind personenbezogene Daten, und in vielen Rechtsordnungen gelten Datenschutzgesetze wie DSGVO und CCPA ab dem Moment, in dem Sie Informationen über identifizierbare Personen erfassen und speichern, selbst wenn diese Informationen öffentlich sind. Das bedeutet, eine rechtmäßige Grundlage für das Erhobene zu haben, nur das Notwendige aufzubewahren und Löschanfragen nachzukommen. Aggregieren Sie, wo möglich (Anzahlen und Trends über viele Repositories), statt Dossiers über namentlich genannte Entwickler anzulegen, und veröffentlichen Sie niemals Details einer Einzelperson oder fügen Sie deren Spuren zu einem Personenprofil zusammen.
Für die meisten Aufgaben ist die offizielle GitHub REST API das bessere Werkzeug. Sie ist großzügig, kostenlos für normale Nutzung und liefert sauberes, strukturiertes JSON für Repositories, Nutzer, Stars, Forks, Sprachen und Topics ohne HTML-Parsing. Sie ist der sanktionierte Weg, übersteht Markup-Änderungen und bietet dokumentierte Ratelimits, die Sie einplanen können. Greifen Sie auf Scraping nur zurück, wenn eine bestimmte öffentliche Seite etwas enthält, das die API nicht bereitstellt, und halten Sie diese Arbeit klein, gedrosselt und auf öffentliche, nicht sensible Felder beschränkt. Wenn Ihr Projekt GitHub-Daten in nennenswertem Umfang benötigt, beginnen Sie mit der REST API, nicht mit einem Scraper.
Wichtigste Erkenntnisse
- GitHub ist serverseitig gerendert, aber ratelimitiert. Eine einfache Anfrage gibt Markup zurück, aber nicht authentifizierter Traffic von einer IP wird schnell gedrosselt, daher leiten Sie Anfragen über rotierende IPs.
- Das normale Token reicht aus. Repository- und Profilseiten benötigen kein JavaScript-Rendering, sodass das günstigere normale Token alles abruft, was Sie brauchen.
-
Auf stabile Hooks setzen. Parsen Sie Repository-Felder über
itemprop-Attribute und Octicon-Icon-Klassen, und Profilfelder übervcard-Klassen, nicht über autogenerierte Utility-Klassen. - Profildaten als personenbezogene Daten behandeln. Grobe öffentliche Felder extrahieren, aggregieren statt Einzelpersonen zu profilieren, und DSGVO sowie CCPA beim Speichern respektieren.
- Die GitHub REST API bevorzugen. Sie ist kostenlos, großzügig und strukturiert; scrapen Sie nur die öffentlichen Seiten, die sie nicht abdeckt, gedrosselt und in kleinem Umfang.
Häufig gestellte Fragen
Benötige ich das normale Token oder das JS-Token für GitHub?
Das normale Token. GitHub rendert Repository- und Profilseiten auf dem Server, sodass das statische HTML bereits Name, Beschreibung, Star- und Fork-Anzahlen, Sprache, Topics und die öffentlichen Profilfelder enthält. Das JS-Token rendert Seiten zunächst in einem Browser und kostet mehr, was Sie nur für die seltene GitHub-Ansicht benötigen, die clientseitiges Rendering voraussetzt.
Welche GitHub-Daten sind sicher zu scrapen?
Öffentliche Daten, die jeder ausgeloggte Besucher sehen kann: Name, Beschreibung, Stars, Forks, Watchers, primäre Sprache und Topics eines öffentlichen Repositories, plus Name, Bio, Anzahl öffentlicher Repositories und Follower-Anzahl eines öffentlichen Profils. Private Repositories, Organisationsmitgliederlisten, E-Mail-Adressen und alles hinter einer Authentifizierung sind tabu, sowohl unter GitHubs Bedingungen als auch, für personenbezogene Daten, unter dem Datenschutzrecht.
Sollte ich stattdessen die GitHub REST API verwenden statt zu scrapen?
Für die meisten Aufgaben: ja. Die offizielle GitHub REST API ist kostenlos für normale Nutzung, großzügig mit ihren Ratelimits und gibt sauberes JSON für Repositories, Nutzer, Stars, Forks, Sprachen und Topics ohne HTML-Parsing zurück. Sie ist der sanktionierte Weg und übersteht Markup-Änderungen. Greifen Sie auf Scraping nur zurück, wenn eine bestimmte öffentliche Seite etwas enthält, das die API nicht bereitstellt, und halten Sie diese Arbeit klein und gedrosselt.
Wie vermeide ich Ratelimiting beim Scrapen von GitHub?
Halten Sie Ihre Pro-IP-Anfragerate niedrig, fügen Sie echte Verzögerungen zwischen Anfragen wie das obige time.sleep(3) hinzu, und routen Sie über rotierende Residential-IPs, damit keine einzelne Adresse ein Limit auslöst. Die Crawling API verwaltet Rotation und Retries für Sie. Beobachten Sie die Statuscodes und reduzieren Sie die Last, sobald Sie Challenges oder Fehler sehen, statt stärker zu drücken.
Warum sind Star- und Follower-Anzahlen Strings wie "59.1k"?
Weil das der abgekürzte Text ist, den GitHub auf der Seite rendert, und das Skript den sichtbaren Text liest. Wenn Sie exakte Ganzzahlen benötigen, schauen Sie sich das title-Attribut des Elements an, das üblicherweise die genaue Zahl enthält, und lesen Sie dieses statt des angezeigten Texts, bevor Sie Arithmetik durchführen.
Kann ich private Repositories oder Nutzer-E-Mail-Adressen scrapen?
Nein, und diese Anleitung zeigt absichtlich nicht, wie. Private Repositories sitzen hinter einer Authentifizierung, und E-Mail-Adressen sind personenbezogene Daten, die GitHub anonymen Besuchern nicht zugänglich macht. Beides zu erreichen würde das Umgehen von Zugriffskontrollen oder das Erfassen personenbezogener Daten ohne rechtmäßige Grundlage bedeuten, was gegen GitHubs Bedingungen und das Datenschutzrecht verstößt. Für den Zugriff auf Konten oder Organisationen, die Sie kontrollieren, authentifizieren Sie sich über die offizielle GitHub REST API.
Crawlen Sie jede Website im großen Maßstab, ohne gegen die Infrastruktur zu kämpfen.
Crawlbase übernimmt Proxys, Fingerprints und CAPTCHAs, damit Ihr Team Datenpipelines ausliefert, statt Crawl-Infrastruktur zu pflegen. 1.000 Anfragen kostenlos, keine Karte erforderlich.
