Як скрапити публічні репозиторії GitHub за допомогою Python?

Коментарі: 0

У цій статті розберемо, як скрапити репозиторії GitHub, використовуючи Python. Розглянемо популярні бібліотеки, такі як BeautifulSoup, Requests, та надамо покроковий підхід, щоб процес можна було відтворити самостійно.

Чому варто скрапити репозиторії GitHub?

Що таке скрапінг GitHub та для чого він потрібен? Є кілька причин скрапити GitHub. Найбільш популярні з них:

  • Слідкувати за технологічними тенденціями. Слідкуючи за зірками та за репозиторіями, можна стежити за поточними тенденціями мов програмування, фреймворків і бібліотек. Ці дані можуть знадобитися при прийнятті рішень щодо впровадження технологій, розвитку навичок і розподілу ресурсів.
  • Отримання доступу до бази знань з програмування. GitHub має безліч проєктів з відкритим кодом, прикладів та рішень. Це означає, що ви можете отримати величезну кількість знань з програмування та передових практик з платформи, що корисно для освітніх цілей, покращення навичок кодування та розуміння того, як реалізуються технології.

GitHub не лише дає можливість розміщувати репозиторії, але й має велику базу активних користувачів та надійну репутацію.

Дані GitHub є цінними для моніторингу технологічних тенденцій, удосконалення програмного забезпечення. Ця інформація відіграє ключову роль у випередженні кокурентів у сфері IT.

Основні бібліотеки та інструменти для скрапінгу GitHub

Python широко використовується для веб-скрапінгу завдяки своєму простому синтаксису та багатому набору бібліотек. Щоб скрапити GitHub за допомогою Python, необхідно встановити такі бібліотеки:

  • Requests: найпопулярніша клієнтська бібліотека для надсилання HTTP-запитів і обробки відповідей.
  • BeautifulSoup: комплектна бібліотека аналізу HTML. Забезпечує надійну навігацію та вилучення даних для скрапінгу.
  • Selenium: запускає реальний браузер, що дає змогу взаємодіяти з елементами на сторінці.

Завдяки цим інструментам для скрапінгу GitHub можна ефективно збирати інформацію. Давайте детально розглянемо, як це зробити.

Створення скрапера для GitHub-репозиторіїв із Beautiful Soup

У цій частині розглянемо, як створити веб-скрапер для збору даних із публічних репозиторіїв GitHub. Основні етапи створення скрапера:

  1. Налаштування середовища – встановлення Python та необхідних бібліотек.
  2. Завантаження HTML-коду сторінки GitHub.
  3. Аналіз структури сторінки – знаходження потрібних елементів.
  4. Витягування даних – отримання назв репозиторіїв, описів, кількості зірок тощо.
  5. Збереження даних у зручному форматі.

Далі покроково розглянемо всі ці етапи та створимо готовий скрипт для скрапінгу.

Крок 1: Налаштування середовища Python-проєкту

Перш ніж почати, переконайтеся, що Python встановлений на вашому комп'ютері. Після цього створіть віртуальне середовище Python:


python -m venv github_scraper
source github_scraper/bin/activate  # Для MacOS та Linux
github_scraper\Scripts\activate     # Для Windows

Крок 2: Встановлення необхідних бібліотек Python

Як згадувалось раніше, BeautifulSoup і Requests допомагають виконувати веб-скрапінг на GitHub. В активному віртуальному середовищі виконайте таку команду, щоб додати їх до залежностей проєкту:


pip install beautifulsoup4 requests

Крок 3: Доступ до цільової сторінки GitHub і її завантаження

Виберіть репозиторій, з якого хочете отримати дані. Спочатку збережемо посилання у змінну, а потім створимо HTTP-запит, щоб отримати код сторінки.


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

Крок 4: Аналіз і розбір HTML-структури сторінки

Щоб проаналізувати HTML-код, передайте його BeautifulSoup:


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

Конструктор BeautifulSoup() приймає два аргументи:

  1. Рядок, що містить вміст HTML: зберігається у page.text змінній.
  2. Синтаксичний аналізатор, який використовуватиме Beautiful Soup: «html.parser» – це назва вбудованого в Python аналізатора HTML.

BeautifulSoup() розбере HTML і поверне структуру дерева, яку можна досліджувати. Докладніше, soup змінна надає ефективні методи вибору елементів з дерева DOM, наприклад:

  • find(): повертає перший елемент HTML, який відповідає стратегії селектора, переданій як параметр.
  • find_all(): повертає список елементів HTML, що відповідають стратегії селектора введення.
  • select_one(): повертає перший HTML-елемент, який відповідає CSS-селектору, переданому як параметр.
  • select(): повертає список HTML-елементів, які відповідають введеному CSS-селектору.

Крок 5: Визначення релевантних даних для збору

Перш ніж зануритись у код, треба виконати ще один важливий крок – це вибір потрібних елементів HTML і вилучення з них даних.

Відкрийте сторінку GitHub та ознайомтеся з нею. Натисніть F12, щоб відкрити інстументи розробників. Відкривши код, ви помітите, що сайт не кваліфікує багато елементів унікальними класами чи атрибутами. Тому, зазвичай непросто перейти до потрібного елемента. Продовжуйте перевіряти сторінку, доки не зрозумієте, що готові зібрати дані.

Крок 6: Витягування деталей репозиторію

Напишемо скрипт для роботи з репозиторіями GitHub на Python та витягнемо корисні дані зі сховища GitHub, такі як кількість зірок, опис, останній комміт тощо. Для цього треба вибрати необхідні атрибути та витягнути текстовий вміст.

  • Назва репозиторію:
    
    repo_title = soup.select_one('[itemprop="name"]').text.strip()
    
    

    Параметр itemprop="name" має унікальний атрибут, тому витягуємо його. Текстові поля GitHub зазвичай містять пробіли та символи нового рядка. Їх можна позбутися за допомогою strip().

  • Поточна гілка:
    
    git_branch_icon_html_element = soup.select_one('[class="Box-sc-g0xbh4-0 ffLUq ref-selector-button-text-container"]').text.split()
    
    

    Зауважте, що немає простого способу вибрати елемент HTML, який зберігає назву головної гілки. Що можна зробити? Вибрати клас, який є унікальним та витягнути текст.

  • Останній комміт:
    
    relative_time_html_element = soup.select_one('relative-time')
    latest_commit = relative_time_html_element['datetime']
    
    

    Ми знайшли тег relative-time, де містяться дані про останній комміт та вибираємо дату через datetime.

Зберемо інформацію, яка знаходиться ліворуч: опис, зірки, перегляди, вилки.

  • Опис:
    
    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(',', '')
    
    

Крок 7: Збір і аналіз файлів readme

У файлі readme лежить важлива інформація. Він описує репозиторії і пояснює, як використовувати код. Якщо відкрити файл readme.md можна побачити, яке посилання він використовує:


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

Оскільки, у нас є , можемо програмно створити URL-адресу за допомогою f-рядка, використати її та створити HTTP-запит, щоб отримати код файлу.


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

Зверніть увагу на перевірку 404, щоб уникнути зберігання вмісту сторінки GitHub 404, якщо в сховищі немає файлу readme.

Крок 8: Організація та збереження зібраних даних

Зберемо всі дані у словник для того, щоб легко записати їх у 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

Крок 9: Експорт даних у формат JSON

Щоб зберегти зібрані дані у форматі JSON для подальшого аналізу, будемо використовувати стандартну бібліотеку Python. Вона добре підходить для зберігання вкладених структур, особливо якщо статті містять списки.


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

Крок 10: Об'єднання всіх етапів у завершений скрипт


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

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

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

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

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

# forks
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)

Висновки

Ми розібралися, як створити скрапер для GitHub-репозиторіїв за допомогою Beautiful Soup і Requests. Тепер ви знаєте, як отримувати дані зі сторінок, витягувати корисну інформацію та зберігати її у зручному форматі. Це може стати в пригоді для аналізу популярних проєктів, моніторингу змін у коді або збору статистики.

Але важливо пам’ятати про відповідальне використання. GitHub має API, який у багатьох випадках буде зручнішим і коректнішим. Якщо ж ви обираєте веб-скрапінг, дотримуйтеся правил сайту та не перевантажуйте сервери.

Коментарії:

0 Коментаріїв