étiqueter. Par exemple :
<div role="rowheader">
<a href="/owner/repo/tree/main/folder-name">folder-name</a>
</div>
Copier après la connexion
Copier après la connexion
3. Implémentation du Scraper
3.1. Fonction d'exploration récursive
Le script grattera récursivement les dossiers et imprimera leur structure. Pour limiter la profondeur de récursion et éviter une charge inutile, nous utiliserons un paramètre de profondeur.
import requests
from bs4 import BeautifulSoup
import time
def crawl_github_folder(url, depth=0, max_depth=3):
"""
Recursively crawls a GitHub repository folder structure.
Parameters:
- url (str): URL of the GitHub folder to scrape.
- depth (int): Current recursion depth.
- max_depth (int): Maximum depth to recurse.
"""
if depth > max_depth:
return
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"Failed to access {url} (Status code: {response.status_code})")
return
soup = BeautifulSoup(response.text, 'html.parser')
# Extract folder and file links
items = soup.select('div[role="rowheader"] a')
for item in items:
item_name = item.text.strip()
item_url = f"https://github.com{item['href']}"
if '/tree/' in item_url:
print(f"{' ' * depth}Folder: {item_name}")
crawl_github_folder(item_url, depth + 1, max_depth)
elif '/blob/' in item_url:
print(f"{' ' * depth}File: {item_name}")
# Example usage
if __name__ == "__main__":
repo_url = "https://github.com/<owner>/<repo>/tree/<branch>/<folder>"
crawl_github_folder(repo_url)
Copier après la connexion
Copier après la connexion
4. Fonctionnalités expliquées
-
En-têtes de requête : Utilisation d'une chaîne User-Agent pour imiter un navigateur et éviter le blocage.
-
Exploration récursive :
- Détecte les dossiers (/tree/) et les saisit de manière récursive.
- Liste les fichiers (/blob/) sans entrer davantage.
-
Indentation : reflète la hiérarchie des dossiers dans la sortie.
-
Limitation de profondeur : empêche une récursion excessive en définissant une profondeur maximale (max_degree).
5. Améliorations
Ces améliorations sont conçues pour améliorer la fonctionnalité et la fiabilité du robot d'exploration. Ils répondent à des défis courants tels que l'exportation des résultats, la gestion des erreurs et le contournement des limites de débit, garantissant ainsi l'efficacité et la convivialité de l'outil.
5.1. Exportation des résultats
Enregistrez la sortie dans un fichier JSON structuré pour une utilisation plus facile.
pip install requests beautifulsoup4
Copier après la connexion
Copier après la connexion
5.2. Gestion des erreurs
Ajoutez une gestion robuste des erreurs pour les erreurs réseau et les modifications HTML inattendues :
<div role="rowheader">
<a href="/owner/repo/tree/main/folder-name">folder-name</a>
</div>
Copier après la connexion
Copier après la connexion
5.3. Limitation du débit
Pour éviter d'être limité par GitHub, introduisez des délais :
import requests
from bs4 import BeautifulSoup
import time
def crawl_github_folder(url, depth=0, max_depth=3):
"""
Recursively crawls a GitHub repository folder structure.
Parameters:
- url (str): URL of the GitHub folder to scrape.
- depth (int): Current recursion depth.
- max_depth (int): Maximum depth to recurse.
"""
if depth > max_depth:
return
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"Failed to access {url} (Status code: {response.status_code})")
return
soup = BeautifulSoup(response.text, 'html.parser')
# Extract folder and file links
items = soup.select('div[role="rowheader"] a')
for item in items:
item_name = item.text.strip()
item_url = f"https://github.com{item['href']}"
if '/tree/' in item_url:
print(f"{' ' * depth}Folder: {item_name}")
crawl_github_folder(item_url, depth + 1, max_depth)
elif '/blob/' in item_url:
print(f"{' ' * depth}File: {item_name}")
# Example usage
if __name__ == "__main__":
repo_url = "https://github.com/<owner>/<repo>/tree/<branch>/<folder>"
crawl_github_folder(repo_url)
Copier après la connexion
Copier après la connexion
6. Considérations éthiques
Rédigée par Shpetim Haxhiu, expert en automatisation logicielle et programmation éthique, cette section garantit le respect des meilleures pratiques lors de l'utilisation du robot GitHub.
-
Conformité : adhérez aux conditions d'utilisation de GitHub.
-
Minimiser la charge : respectez les serveurs de GitHub en limitant les requêtes et en ajoutant des délais.
-
Autorisation : obtenez l'autorisation pour une exploration approfondie des référentiels privés.
7. Code complet
Voici le script consolidé avec toutes les fonctionnalités incluses :
import json
def crawl_to_json(url, depth=0, max_depth=3):
"""Crawls and saves results as JSON."""
result = {}
if depth > max_depth:
return result
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers)
if response.status_code != 200:
print(f"Failed to access {url}")
return result
soup = BeautifulSoup(response.text, 'html.parser')
items = soup.select('div[role="rowheader"] a')
for item in items:
item_name = item.text.strip()
item_url = f"https://github.com{item['href']}"
if '/tree/' in item_url:
result[item_name] = crawl_to_json(item_url, depth + 1, max_depth)
elif '/blob/' in item_url:
result[item_name] = "file"
return result
if __name__ == "__main__":
repo_url = "https://github.com/<owner>/<repo>/tree/<branch>/<folder>"
structure = crawl_to_json(repo_url)
with open("output.json", "w") as file:
json.dump(structure, file, indent=2)
print("Repository structure saved to output.json")
Copier après la connexion
En suivant ce guide détaillé, vous pouvez créer un robot d'exploration de dossiers GitHub robuste. Cet outil peut être adapté à divers besoins tout en garantissant le respect de l'éthique.
N'hésitez pas à laisser des questions dans la section commentaires ! N'oubliez pas non plus de me contacter :
-
Email : shpetim.h@gmail.com
-
LinkedIn : linkedin.com/in/shpetimhaxhiu
-
GitHub : github.com/shpetimhaxhiu
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!