Jak skrobać publiczne repozytoria GitHub za pomocą Pythona?

Komentarze: 0

W tym artykule przeanalizujemy, jak skrobać repozytoria GitHub za pomocą Pythona. Dokonamy przeglądu dobrze znanych bibliotek, takich jak BeautifulSoup i Requests, a także podamy szczegółowe wyjaśnienie podczas tworzenia skryptu skrobiącego GitHub, abyś mógł łatwo śledzić.

Dlaczego warto skrobać repozytoria GitHub?

Czym jest scraping Github i do czego służy? Istnieje wiele celów jego wykorzystania, ale do najczęstszych należą:

  • Monitorowanie postępu technologicznego. Monitorowanie gwiazd i repozytoriów to świetny sposób na śledzenie trendów w językach programowania, frameworkach i bibliotekach. Informacje te mogą być bardzo ważne przy podejmowaniu decyzji związanych z wdrażaniem technologii, rozwojem umiejętności lub alokacją zasobów.
  • Wykorzystanie repozytorium programistycznego. Na GitHub można znaleźć mnóstwo projektów, przykładów i rozwiązań open source. W związku z tym na platformie dostępna jest ogromna ilość wiedzy i technik programistycznych przydatnych do celów edukacyjnych, doskonalenia umiejętności programowania i zrozumienia implementacji technologii.

GitHub nie tylko oferuje hosting repozytoriów, ale ma też ogromną bazę użytkowników, a świetna reputacja sprawia, że jest to niezawodna opcja.

Informacje przechowywane na GitHub są przydatne do śledzenia wzorców postępu technologicznego, a także do ulepszania rozwoju oprogramowania. Informacje te mają kluczowe znaczenie dla dotrzymania kroku konkurentom w świecie technologii informatycznych.

Niezbędne biblioteki i narzędzia do skrobania GitHub

Jeśli chodzi o skrobanie stron internetowych, najłatwiejszym językiem do pracy jest Python, ponieważ jego biblioteki i moduły są tak liczne. Aby Github skrobał Pythona, należy dodać następujące moduły:

  • requests: klient lib, który przechowuje żądania i odpowiedzi HTTP i jest najczęściej używany.
  • BeautifulSoup: zaawansowany, jeśli chodzi o wyodrębnianie szczegółów z HTML, ponieważ posiada zaawansowane funkcje nawigacji i pobierania danych.
  • Selenium: uruchamia prawdziwą przeglądarkę i umożliwia klikanie i wpisywanie elementów strony.

Można to łatwo zrobić za pomocą narzędzi do skrobania Github. Przyjrzyjmy się jednak, jak to zrobić.

Tworzenie skryptu do skrobania repozytorium GitHub za pomocą Beautiful Soup

Ta część pokaże, jak skrobać repozytoria Github. Ważne kroki w tworzeniu scrapera składają się z:

  1. Tworzenie bazy zestawów - co wiąże się z pobraniem Pythona i odpowiednich bibliotek.
  2. Zapisanie kodu HTML strony GitHub.
  3. Sprawdzenie układu strony w celu zidentyfikowania potrzebnych elementów.
  4. Zbieranie informacji, które obejmuje między innymi nazwy kont, opisy i liczbę zdobytych gwiazdek.
  5. Przechowywanie danych w typach systemów plików.

Od teraz będziemy udostępniać szczegóły dotyczące wszystkich tych kroków wraz z w pełni uformowanym skryptem skrobiącym Github.

Krok 1: Konfiguracja środowiska projektu Python

Upewnij się, że masz Pythona na swoim komputerze. Następnie utwórz nowe wirtualne środowisko Python, aby rozpocząć proces skrobania Github.


python -m venv github_scraper
source github_scraper/bin/activate  # Dla systemów MacOS i Linux
github_scraper\Scripts\activate     # Dla systemu Windows

Krok 2: Instalacja wymaganych bibliotek Pythona

Jak wspomnieliśmy wcześniej, BeautifulSoup i Requests pomogą w skrobaniu repozytoriów GitHub. W aktualnie aktywowanym środowisku wirtualnym wykonaj to polecenie, aby dołączyć je do zależności projektu:


pip install beautifulsoup4 requests

Krok 3: Uzyskanie dostępu i pobranie docelowej strony GitHub

Wybierz dowolne repozytorium, z którego chcesz wykonać scraping Github. Najpierw zdefiniuj link w zmiennej, a następnie wykonaj żądanie HTTP, które pobierze kod strony.


url = "https://github.com/TheKevJames/coveralls-python"
response = requests.get(url)

Krok 4: Zrozumienie i analizowanie struktury HTML

Aby przeanalizować kod HTML, należy wprowadzić go do BeautifulSoup.


soup = BeautifulSoup(page.text, 'html.parser')

Konstruktor BeautifulSoup() musi posiadać dwie rzeczy.

  1. Ciąg znaków zawierający treść HTML, przechowywany w zmiennej page.text.
  2. Parser, który będzie używany przez Beautiful Soup: "html.parser" to nazwa wbudowanego parsera HTML Pythona.

HTML zostanie przeanalizowany przez BeautifulSoup i zostanie wygenerowana struktura drzewa. Dokładniej, zmienna soup zawiera wszystkie metody wymagane do wybrania odpowiednich elementów z drzewa DOM, takich jak:

  • find(): zwraca pierwszy element HTML, który odpowiada podanej strategii selektora.
  • find_all(): zwraca listę elementów HTML pasujących do strategii selektora wejściowego.
  • select_one(): zwraca pierwszy element HTML, który pasuje do wprowadzonego selektora CSS.
  • select(): zwraca listę elementów HTML odpowiadających podanemu selektorowi CSS.

Krok 5: Analiza strony docelowej pod kątem istotnych danych

Oto kolejny ważny krok: wybranie prostych elementów HTML i zeskrobanie z nich danych Github. Ten krok poprzedza faktyczne napisanie skryptu repozytoriów Github w Pythonie.

Przed skrobaniem Githuba należy zapoznać się z samą stroną internetową. Następnie otwórz narzędzia deweloperskie, klikając F12. Po otwarciu kodu zauważysz, że wiele elementów na stronie nie ma unikalnych klas lub atrybutów, które ułatwiłyby nawigację do odpowiedniego elementu. Przejrzyj stronę i przygotuj się do wyodrębnienia danych.

Krok 6: Wyodrębnianie szczegółów repozytorium

Teraz jesteśmy gotowi do stworzenia skryptu Python, który pomoże nam w skrobaniu repozytoriów GitHub. Ten skrypt może wyodrębnić przydatne informacje przechowywane w GitHub, takie jak gwiazdki, opisy, ostatnie zatwierdzenia itp. W tym celu musimy określić wymagane funkcje i pobrać odpowiadające im wartości tekstowe.

  • Nazwa repozytorium:
    
    repo_title = soup.select_one('[itemprop="name"]').text.strip()
    

    Atrybut itemprop="name" ma wartość atrybutu, która ma unikalną tożsamość, więc pobieramy ją. Pola tekstowe na GitHub zazwyczaj zawierają spacje i znaki nowej linii i można je wyczyścić za pomocą funkcji strip().

  • Obecny oddział:
    
    git_branch_icon_html_element = soup.select_one('[class="Box-sc-g0xbh4-0 ffLUq ref-selector-button-text-container"]').text.split()
    

    Zwróć uwagę na fakt, że nie ma prostszej metody wyboru elementu HTML, który posiada tytuł głównej gałęzi. Co możesz zrobić? Wybierz klasę, która jest unikalna i pobierz tekst.

  • Ostatnie zatwierdzenie:
    
    relative_time_html_element = soup.select_one('relative-time')
    latest_commit = relative_time_html_element['datetime']
    

    Zauważyliśmy, że znacznik czasu względnego, w którym przechowywane było ostatnie zatwierdzenie przez użytkownika, był już wybrany, a data została wybrana za pomocą datetime.

Zbierz informacje, które znajdują się po lewej stronie: opis, gwiazdki, widoki, rozwidlenia.

  • Opis:
    
    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()
    
  • Stars:
    
    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(',', '')
    
  • Widoki:
    
    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(',', '')
    
  • Widelce:
    
    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(',', '')
    

Krok 7: Zbieranie i analiza plików Readme

Plik readme jest bardzo ważny. Zawiera opisy repozytoriów i instrukcje dotyczące implementacji kodu. W przypadku sprawdzenia pliku readme.md można zauważyć, jaki link zawiera:


https://raw.githubusercontent.com///readme.md

Ponieważ mamy , możemy programowo utworzyć adres URL za pomocą ciągu f, użyć go i wykonać żądanie HTTP, aby uzyskać kod pliku.


readme_url = f'https://github.com/TheKevJames/coveralls-python/blob/{main_branch}/readme.rst'
readme_page = requests.get(readme_url)

readme = None
if readme_page.status_code != 404:
    readme = readme_page.text

Pamiętaj, aby sprawdzić błąd 404, aby uniknąć zapisania zawartości strony GitHub 404, jeśli repozytorium nie ma pliku readme.

Krok 8: Efektywne organizowanie i przechowywanie zebranych danych

Wszystkie informacje będą przechowywane w jednym słowniku, dzięki czemu możemy łatwo zapisać je w pliku JSON.


repo = {}
repo['name'] = repo_title
repo['latest_commit'] = latest_commit
repo['main_branch'] = main_branch
repo['description'] = description
repo['stars'] = stars
repo['watchers'] = watchers
repo['forks'] = forks
repo['readme'] = readme

Krok 9: Eksportowanie zeskrobanych danych w formacie JSON

Wykorzystamy wbudowaną bibliotekę Pythona do analizy danych i przechowywania ich w formacie JSON, ponieważ jest to idealne rozwiązanie dla zagnieżdżonych struktur, takich jak w naszym przypadku, gdy artykuły mają listy.


with open('github_data.json', 'w', encoding='utf-8') as json_file:
  json.dump(repo, json_file, ensure_ascii=False, indent=4)

Krok 10: Integracja wszystkich kroków w kompletny skrypt


import json
import requests
from bs4 import BeautifulSoup

url = "https://github.com/TheKevJames/coveralls-python"
response = requests.get(url)
soup = BeautifulSoup(response.text, "lxml")

repo_title = soup.select_one('[itemprop="name"]').text.strip()

# oddział
main_branch = soup.select_one(
   '[class="Box-sc-g0xbh4-0 ffLUq ref-selector-button-text-container"]').text.split()

# najnowsze zatwierdzenie
relative_time_html_element = soup.select_one('relative-time')
latest_commit = relative_time_html_element['datetime']

# opis
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()

# gwiazdy
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(',', '')

# obserwatorzy
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(',', '')

# widelce
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(',', '')

# readme
readme_url = f'https://github.com/TheKevJames/coveralls-python/blob/{main_branch}/readme.rst'
readme_page = requests.get(readme_url)

readme = None
if readme_page.status_code != 404:
   readme = readme_page.text

repo = {}
repo['name'] = repo_title
repo['latest_commit'] = latest_commit
repo['main_branch'] = main_branch
repo['description'] = description
repo['stars'] = stars
repo['watchers'] = watchers
repo['forks'] = forks
repo['readme'] = readme

with open('github_data.json', 'w', encoding='utf-8') as json_file:
   json.dump(repo, json_file, ensure_ascii=False, indent=4)

Scraping Github: Podsumowanie

Przeanalizowaliśmy proces tworzenia skryptu skrobiącego GitHub dla repozytoriów za pomocą BeautifulSoup i Requests. Wiesz już, jak uzyskać dostęp do stron internetowych, wyciągnąć odpowiednie dane i zakodować je w przyjazny dla użytkownika sposób. Takie umiejętności przydadzą się w analizie znanych projektów, śledzeniu zmian w kodzie czy generowaniu raportów.

Niemniej jednak należy dbać o rozsądne użytkowanie. W większości przypadków API jest dostępne do użytku na GitHub, co będzie prostsze i bardziej praktyczne w pracy. Jeśli zdecydujesz się na skrobanie stron internetowych, upewnij się, że przestrzegasz wytycznych witryny i nie bombardujesz serwerów zbyt dużą liczbą żądań.

Komentarze:

0 komentarze