Как скрапить публичные репозитории GitHub с помощью Python?

Комментарии: 0

В данной статье рассматривается процесс скрапинга репозиториев GitHub с использованием Python. Проанализируем популярные библиотеки, такие как BeautifulSoup и Requests, с предложением пошагового подхода для воспроизведения процесса.

Почему стоит скрапить репозитории 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-контент, сохраненный в переменной response.text.
  2. Парсер, который будет использовать BeautifulSoup: 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

readme может быть None, если страница возвращает статус 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 комментариев