Ce tutoriel abordera les sujets suivants :
- Pourquoi chercher dans les dépôts GitHub ?
- Bibliothèques et outils de scraping GitHub
- Construire un scraper de repo GitHub avec Beautiful Soup
Pourquoi chercher dans les dépôts GitHub ?
Il y a plusieurs raisons de récupérer les dépôts GitHub. Les plus populaires sont les suivants :
- Suivre les tendances technologiques : En suivant les étoiles et les versions du dépôt, vous pouvez vous tenir au courant des tendances actuelles en matière de langages de programmation, de cadres et de bibliothèques. L’exploration de GitHub vous permet d’analyser les technologies qui gagnent en popularité afin de suivre leur croissance et d’identifier les tendances émergentes. Ces données peuvent guider les décisions relatives à l’adoption des technologies, au développement des compétences et à l’allocation des ressources.
- Accéder à une riche base de connaissances en programmation : GitHub est un trésor de projets, d’échantillons de code et de solutions à source ouverte. Cela signifie que vous pouvez acquérir une grande quantité de connaissances et de bonnes pratiques en matière de programmation à partir de la plateforme. Cela est utile à des fins éducatives, pour améliorer les compétences en matière de codage et pour comprendre comment les différentes technologies sont mises en œuvre.
- Obtenir des informations sur le développement de la collaboration : Les référentiels offrent un aperçu de la façon dont les développeurs collaborent par le biais de demandes de téléchargement, de problèmes et de discussions. En collectant ces données, vous pouvez étudier les modes de collaboration pour vous aider à concevoir des stratégies de travail en équipe, à améliorer la gestion des projets et à perfectionner les processus de développement de logiciels.
GitHub n’est pas la seule plateforme basée sur le cloud pour l’hébergement de dépôts git, et il existe de nombreuses alternatives. Cependant, il reste le choix préféré pour le scraping de données en raison de ses caractéristiques :
- Large base d’utilisateurs
- Forte activité des utilisateurs
- Une réputation établie
En particulier, les données de GitHub sont précieuses pour suivre les tendances technologiques, découvrir des bibliothèques et des cadres, et améliorer le processus de développement de logiciels. Ces informations jouent un rôle clé pour rester en tête de la concurrence dans le monde des technologies de l’information.
Bibliothèques et outils de scraping GitHub
Python est largement considéré comme un excellent langage pour le web scraping grâce à sa syntaxe simple, sa nature conviviale pour les développeurs et son large éventail de bibliothèques. Voici pourquoi il s’agit du langage de programmation recommandé pour le scraping de GitHub. Pour en savoir plus, consultez notre guide détaillé sur comment faire du web scraping avec Python.
L’étape suivante consiste à sélectionner la bibliothèque de scraping la plus appropriée parmi le large éventail d’options disponibles. Pour prendre une décision éclairée, vous devez d’abord explorer la plateforme dans votre navigateur. Ouvrez les DevTools et jetez un coup d’œil aux appels AJAX effectués par les pages du dépôt sur GitHub. Vous constaterez que la plupart d’entre eux peuvent être ignorés. En fait, la plupart des données de la page sont intégrées dans les documents HTML renvoyés par le serveur.
Cela implique qu’une bibliothèque permettant d’effectuer des requêtes HTTP vers le serveur, combinée à un analyseur HTML, suffira à la tâche. Vous devriez donc opter pour :
- Requests: La bibliothèque client HTTP la plus populaire de l’écosystème Python. Il rationalise le processus d’envoi des requêtes HTTP et le traitement des réponses correspondantes.
- Beautiful Soup: Une bibliothèque complète d’analyse HTML et XML. Il fournit une API robuste de navigation dans le DOM et d’extraction de données pour le web scraping.
Grâce à Requests et Beautiful Soup, il est possible d’effectuer du scraping GitHub en utilisant Python. Entrons dans les détails de la manière d’y parvenir !
Construire un grattoir de repo GitHub avec Beautiful Soup
Suivez ce tutoriel étape par étape et apprenez à scraper GitHub en Python. Vous voulez éviter tout le processus de codage et d’extraction ?
Étape 1 : configuration du projet Python
Avant de commencer, assurez-vous que vous remplissez les conditions préalables ci-dessous :
- Python 3+ installé sur votre ordinateur: Téléchargez le programme d’installation, l’exécuter, et suivre les instructions.
Vous avez maintenant tout ce qu’il faut pour mettre en place un projet en Python !
Lancez les commandes suivantes dans le terminal pour créer un dossier github-scraper et l’initialiser avec un environnement virtuel Python:
mkdir github-scraper
cd github-scraper
python -m venv env
Sous Windows, exécutez la commande ci-dessous pour activer l’environnement :
env\Scripts\activate.ps1
Sous Linux ou macOS, exécutez :
./env/bin/activate
Ensuite, ajoutez un fichier scraper.py
contenant la ligne ci-dessous dans le dossier du projet :
print('Hello, World!')
Pour l’instant, votre scraper GitHub n’imprime que “Hello, World !”, mais il contiendra bientôt la logique permettant d’extraire des données de dépôts publics.
Vous pouvez lancer le script avec :
python scraper.py
Si tout s’est déroulé comme prévu, le message suivant devrait s’afficher dans le terminal :
Hello, World!
Maintenant que vous savez que cela fonctionne, ouvrez le dossier du projet dans votre IDE Python préféré.
Formidable ! Préparez-vous à écrire du code Python.
Étape 2 : installez les bibliothèques de web scraping
Comme mentionné précédemment, Beautiful Soup et Requests vous aident à effectuer du web scraping sur GitHub. Dans l’environnement virtuel activé, exécutez la commande suivante pour les ajouter aux dépendances du projet :
pip install beautifulsoup4 requests
Clear scraper.py
puis importez les deux paquets avec ces lignes :
import requestsfrom bs4 import BeautifulSoup
# scraping logic...
Il se peut que vous receviez des avertissements en raison d’importations inutilisées. Ignorez-les, car vous êtes sur le point d’utiliser ces bibliothèques de scraping pour extraire des données de dépôt de GitHub !
Sélectionnez un dépôt GitHub dont vous souhaitez récupérer les données. Dans ce guide, vous verrez comment récupérer le dépôt luminati-proxy. Gardez à l’esprit que n’importe quel autre référentiel fera l’affaire, puisque la logique de scraping sera la même.
Voici à quoi ressemble la page cible dans le navigateur :
Stocker l’URL de la page cible dans une variable :
url = 'https://github.com/luminati-io/luminati-proxy'
Ensuite, téléchargez la page avec requests.get():
page = requests.get(url)
En coulisses, requests
effectue une requête HTTP GET à cette URL et enregistre la réponse produite par le serveur dans la variable page
. Ce qui doit retenir votre attention, c’est l’attribut textuel. Il contient le document HTML associé à la page web cible. Vérifiez cela avec une simple instruction print
:
print(page.text)
Lancez le scraper et vous devriez voir ceci dans le terminal :
<!DOCTYPE html>
<html lang="en" data-color-mode="dark" data-light-theme="light" data-dark-theme="dark" data-a11y-animated-images="system" data-a11y-link-underlines="false">
<head>
<meta charset="utf-8">
<link rel="dns-prefetch" href="https://github.githubassets.com">
<link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
<link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
<link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
<link rel="preconnect" href="https://github.githubassets.com" crossorigin>
<link rel="preconnect" href="https://avatars.githubusercontent.com">
<!-- Omitted for brevity... -->
Awesome! Let’s now learn how to parse this
Étape 4 : Analyse du document HTML
Pour analyser le document HTML récupéré ci-dessus, passez-le à Beautiful Soup :
soup = BeautifulSoup(page.text, 'html.parser')
Le constructeur BeautifulSoup()
prend deux arguments :
- La chaîne de caractères contenant le contenu HTML : Ici stockée dans la variable
page.text
. - L’analyseur que Beautiful Soup va utiliser : “
html.parser
“est le nom de l’analyseur HTML intégré à Python.
BeautifulSoup()
analyse le code HTML et renvoie une structure arborescente explorable. En détail, la variable soupe
fournit des méthodes efficaces pour sélectionner des éléments dans l’arbre DOM, tels que :
find()
: renvoie le premier élément HTML correspondant à la stratégie de sélection passée en paramètre.find_all()
: renvoie la liste des éléments HTML correspondant à la stratégie du sélecteur d’entrée.select_one()
: renvoie le premier élément HTML correspondant au sélecteur CSS passé en paramètre.select()
: renvoie la liste des éléments HTML correspondant au sélecteur CSS saisi.
Notez que ces méthodes peuvent également être appelées sur un seul nœud de l’arbre. En plus de ces éléments, l’objet nœud de Beautiful Soup expose également :
find_next_sibling()
: renvoie le premier nœud HTML dans les frères et sœurs de l’élément qui correspond au sélecteur CSS donné.find_next_siblings()
: renvoie tous les nœuds HTML dans les frères et sœurs de l’élément correspondant au sélecteur CSS passé en paramètre.
Grâce à ces fonctions, vous êtes prêt à scraper GitHub. Voyons comment !
Étape 5 : Se familiariser avec la page cible
Avant de se lancer dans le codage, il y a une autre étape cruciale à franchir. L’extraction de données d’un site consiste à sélectionner les éléments HTML intéressants et à en extraire des données. Définir une stratégie de sélection efficace n’est pas toujours facile, et vous devez consacrer du temps à l’analyse de la structure de votre page web cible.
Ouvrez donc la page la page cible de GitHub dans le navigateur et familiarisez-vous avec elle. Cliquez avec le bouton droit de la souris et sélectionnez “Inspecter” pour ouvrir la fenêtre DevTools :
En creusant dans le code HTML, vous remarquerez que le site ne qualifie pas un grand nombre de ses éléments avec des classes ou des attributs uniques. Il est donc généralement difficile de naviguer jusqu’à l’élément souhaité et il se peut que vous deviez passer par les frères et sœurs d’une manière délicate.
Mais ne vous inquiétez pas. Concevoir des stratégies de sélection efficaces pour GitHub n’est peut-être pas facile, mais ce n’est pas non plus impossible. Continuez à inspecter la page dans les DevTools jusqu’à ce que vous vous sentiez prêt à la gratter !
Étape 6 : Extraire les données de la base de données
L’objectif est d’extraire des données utiles du dépôt GitHub, telles que les étoiles, la description, le dernier commit, etc. Vous devez donc initialiser un dictionnaire Python pour garder une trace de ces données. Ajoutez à votre code :
repo = {}
Inspectez d’abord l’élément name :
Notez qu’il possède un attribut itemprop="name"
distinctif. Sélectionnez-le et extrayez son contenu textuel avec :
name_html_element = soup.select_one('[itemprop="name"]')name = name_html_element.text.strip()
Étant donné un nœud Beautiful Soup, utilisez la méthode get_text()
pour accéder à son contenu textuel.
Si vous inspectez name_html_element.text
dans le débogueur, vous verrez :
\nluminati-proxy\n
Les champs de texte de GitHub ont tendance à contenir des espaces et des nouvelles lignes. Débarrassez-vous-en avec la fonction Python strip()
Python.
Juste en dessous du nom du repo, il y a le sélecteur de branche :
Notez qu’il n’y a pas de moyen facile de sélectionner l’élément HTML qui stocke le nom de la branche principale. Vous pouvez sélectionner le nœud .octicon-git-branch
et rechercher la cible span
dans ses frères et sœurs :
git_branch_icon_html_element = soup.select_one('.octicon-git-branch')
main_branch_html_element = git_branch_icon_html_element.find_next_sibling('span')
main_branch = main_branch_html_element.get_text().strip()
Le modèle permettant d’atteindre un élément d’intérêt par l’intermédiaire des frères et sœurs d’une icône est très efficace sur GitHub. Vous le verrez utilisé à plusieurs reprises dans cette section.
Concentrez-vous maintenant sur l’en-tête de la branche :
Extraire la dernière heure de livraison avec :
relative_time_html_element = boxheader_html_element.select_one('relative-time')
latest_commit = relative_time_html_element['datetime']
Étant donné un nœud, vous pouvez accéder à ses attributs HTML comme dans un dictionnaire Python.
Une autre information importante dans cette section est le nombre de commits :
Recueillez-la à l’aide du modèle d’icône décrit précédemment :
history_icon_html_element = boxheader_html_element.select_one('.octicon-history')
commits_span_html_element = history_icon_html_element.find_next_sibling('span')
commits_html_element = commits_span_html_element.select_one('strong')
commits = commits_html_element.get_text().strip().replace(',', '')
Notez que find_next_sibling()
ne donne accès qu’aux frères et sœurs de premier niveau. Pour sélectionner l’un de leurs enfants, vous devez d’abord obtenir l’élément frère, puis appeler select_one()
comme indiqué ci-dessus.
Comme les nombres supérieurs à mille contiennent une virgule dans GitHub, supprimez-la avec la méthode replace()
méthode Python.
Ensuite, portez votre attention sur la boîte d’information à droite :
Sélectionnez-le avec :
bordergrid_html_element = soup.select_one('.BorderGrid')
Inspecter l’élément de description :
Là encore, vous pouvez le sélectionner par l’intermédiaire d’un frère ou d’une sœur :
about_html_element = bordergrid_html_element.select_one('h2')
description_html_element = about_html_element.find_next_sibling('p')
description = description_html_element.get_text().strip()
Ensuite, appliquez le modèle d’icône pour récupérer les étoiles, les montres et les fourchettes du dépôt.
Concentrez-vous sur les icônes, puis sur leurs frères et sœurs textuels :
star_icon_html_element = bordergrid_html_element.select_one('.octicon-star')
stars_html_element = star_icon_html_element.find_next_sibling('strong')
stars = stars_html_element.get_text().strip().replace(',', '')
eye_icon_html_element = bordergrid_html_element.select_one('.octicon-eye')
watchers_html_element = eye_icon_html_element.find_next_sibling('strong')
watchers = watchers_html_element.get_text().strip().replace(',', '')
fork_icon_html_element = bordergrid_html_element.select_one('.octicon-repo-forked')
forks_html_element = fork_icon_html_element.find_next_sibling('strong')
forks = forks_html_element.get_text().strip().replace(',', '')
Bravo ! Vous venez de récupérer un dépôt GitHub.
Étape 7 : Récupérer le fichier readme
Une autre information essentielle à récupérer est le fichier README.md
. Il s’agit d’un fichier texte facultatif qui décrit le dépôt GitHub et explique comment utiliser le code.
Si vous cliquez sur le fichier README.md
puis sur le bouton “Raw”, vous serez redirigé vers l’URL ci-dessous :
https://raw.githubusercontent.com/luminati-io/luminati-proxy/master/README.md
On peut donc en déduire que l’URL du fichier readme d’un repo GitHub suit le format ci-dessous :
https://raw.githubusercontent.com/<repo_id>/<repo_main_branch>/README.md
Puisque vous avez l’information <repo_main_branch> ;
stockée dans la variable main_branch
, vous pouvez construire programmatiquement cette URL avec une f-string Python :
readme_url = f'https://raw.githubusercontent.com/luminati-io/luminati-proxy/{main_branch}/README.md'
Ensuite, utilisez les requêtes pour récupérer le contenu Markdown brut du readme :
readme_url = f'https://raw.githubusercontent.com/luminati-io/luminati-proxy/{main_branch}/README.md'
readme_page = requests.get(readme_url)
readme = None
# if there is a README.md file
if readme_page.status_code != 404:
readme = readme_page.text
Notez la vérification 404 pour éviter de stocker le contenu de la page 404 de GitHub lorsque le repo n’a pas de fichier readme.
Étape 8 : Stocker les données extraites
N’oubliez pas d’ajouter les variables de données scrapées au dictionnaire repo
:
repo['name'] = name
repo['latest_commit'] = latest_commit
repo['commits'] = commits
repo['main_branch'] = main_branch
repo['description'] = description
repo['stars'] = stars
repo['watchers'] = watchers
repo['forks'] = forks
repo['readme'] = readme
Utilisez print(repo)
pour vous assurer que le processus d’extraction des données fonctionne comme prévu. Exécutez le scraper Python GitHub et vous obtiendrez :
{'name': 'luminati-proxy', 'latest_commit': '2023-08-09T08:25:15Z', 'commits': '1079', 'main_branch': 'master', 'description': 'Luminati HTTP/HTTPS Proxy manager', 'stars': '645', 'watchers': '55', 'forks': '196', 'readme': '# Proxy manager\n\n (omitted for brevity...)'}
Formidable ! Vous savez comment récupérer GitHub !
La dernière étape consiste à faciliter le partage, la lecture et l’analyse des données collectées. La meilleure façon d’y parvenir est d’exporter les données dans un format lisible par l’homme, tel que JSON :
import json
# ...
with open('repo.json', 'w') as file:
json.dump(repo, file, indent=4)
Importer json de la bibliothèque standard Python, initialiser un fichier repo.json avec open() , et enfin utiliser json.ump() pour le remplir. et enfin utiliser json.ump() pour le remplir.
Excellent ! Il est temps de jeter un coup d’œil à l’ensemble du scraper GitHub Python.
Voici à quoi ressemble le fichier complet scraper.py
:
import requests
from bs4 import BeautifulSoup
import json
# the URL of the target repo to scrape
url = 'https://github.com/luminati-io/luminati-proxy'
# download the target page
page = requests.get(url)
# parse the HTML document returned by the server
soup = BeautifulSoup(page.text, 'html.parser')
# initialize the object that will contain
# the scraped data
repo = {}
# repo scraping logic
name_html_element = soup.select_one('[itemprop="name"]')
name = name_html_element.get_text().strip()
git_branch_icon_html_element = soup.select_one('.octicon-git-branch')
main_branch_html_element = git_branch_icon_html_element.find_next_sibling('span')
main_branch = main_branch_html_element.get_text().strip()
# scrape the repo history data
boxheader_html_element = soup.select_one('.Box .Box-header')
relative_time_html_element = boxheader_html_element.select_one('relative-time')
latest_commit = relative_time_html_element['datetime']
history_icon_html_element = boxheader_html_element.select_one('.octicon-history')
commits_span_html_element = history_icon_html_element.find_next_sibling('span')
commits_html_element = commits_span_html_element.select_one('strong')
commits = commits_html_element.get_text().strip().replace(',', '')
# scrape the repo details in the right box
bordergrid_html_element = soup.select_one('.BorderGrid')
about_html_element = bordergrid_html_element.select_one('h2')
description_html_element = about_html_element.find_next_sibling('p')
description = description_html_element.get_text().strip()
star_icon_html_element = bordergrid_html_element.select_one('.octicon-star')
stars_html_element = star_icon_html_element.find_next_sibling('strong')
stars = stars_html_element.get_text().strip().replace(',', '')
eye_icon_html_element = bordergrid_html_element.select_one('.octicon-eye')
watchers_html_element = eye_icon_html_element.find_next_sibling('strong')
watchers = watchers_html_element.get_text().strip().replace(',', '')
fork_icon_html_element = bordergrid_html_element.select_one('.octicon-repo-forked')
forks_html_element = fork_icon_html_element.find_next_sibling('strong')
forks = forks_html_element.get_text().strip().replace(',', '')
# build the URL for README.md and download it
readme_url = f'https://raw.githubusercontent.com/luminati-io/luminati-proxy/{main_branch}/README.md'
readme_page = requests.get(readme_url)
readme = None
# if there is a README.md file
if readme_page.status_code != 404:
readme = readme_page.text
# store the scraped data
repo['name'] = name
repo['latest_commit'] = latest_commit
repo['commits'] = commits
repo['main_branch'] = main_branch
repo['description'] = description
repo['stars'] = stars
repo['watchers'] = watchers
repo['forks'] = forks
repo['readme'] = readme
# export the scraped data to a repo.json output file
with open('repo.json', 'w') as file:
json.dump(repo, file, indent=4)
En moins de 100 lignes de code, vous pouvez construire un araignée web pour collecter des données de repo.
Exécuter le script avec :
python scraper.py
Attendez que le processus de scraping se termine, et vous trouverez un fichier repo.json
dans le dossier racine de votre projet. Ouvrez-le et vous verrez :
{
"name": "luminati-proxy",
"latest_commit": "2023-08-09T08:25:15Z",
"commits": "1079",
"main_branch": "master",
"description": "Luminati HTTP/HTTPS Proxy manager",
"stars": "645",
"watchers": "55",
"forks": "196",
"readme": "# Proxy manager\n\n[![dependencies Status](https://david-dm.org/luminati-io/luminati-proxy/status.svg)](https://david-dm.org/luminati-io/luminati-proxy)\n[![devDependencies Status](https://david-dm.org/luminati-io/luminati-proxy/dev-status.svg)](https://david-dm..."
}
Félicitations !
Conclusion
Dans ce guide étape par étape, vous avez compris les raisons pour lesquelles vous devriez construire un GitHub repo scraper. Plus précisément, vous avez appris à explorer GitHub dans un tutoriel guidé.
Parallèlement, de plus en plus de sites adoptent des technologies anti-scraping. Ceux-ci peuvent identifier et bloquer les requêtes par le biais d’une interdiction d’IP et d’une limitation de débit, empêchant ainsi votre scraper d’accéder au site. Le meilleur moyen de les éviter est d’utiliser un proxy. Explorez la vaste offre de Bright Data de services proxy de premier ordre et de proxies GitHub dédiés.
Bright Data contrôle les meilleurs proxys au monde pour le web scraping, au service des entreprises du Fortune 500 et de plus de 20 000 clients. Son réseau mondial de proxys comprend :
- Des proxies de centres de données : plus de 770 000 adresses IP de centres de données.
- Des proxys résidentiels : plus de 72 millions d’adresses IP résidentielles dans plus de 195 pays.
- Des proxies de FAI : plus de 700 000 adresses IP de FAI.
- Des proxies mobiles : plus de 7 millions d’adresses IP mobiles.
Aucune carte de crédit requise
Remarque : ce guide a été testé de manière approfondie par notre équipe au moment de sa rédaction, mais comme les sites web modifient fréquemment leur code et leur structure, il se peut que certaines étapes ne fonctionnent plus comme prévu.