В этом руководстве рассматриваются следующие темы:
- Зачем парсить репозитории GitHub?
- Библиотеки и инструменты для парсинга GitHub
- Создайте парсер для репозитория GitHub с помощью Beautiful Soup
Зачем нужно парсить репозитории GitHub?
Есть несколько причин для парсинга репозиториев GitHub. Вот самые популярные из них:
- Следите за технологическими тенденциями: отслеживая звезды и релизы репозитория, вы можете отслеживать текущие тенденции в языках программирования, фреймворках и библиотеках. Парсинг GitHub позволяет анализировать, какие технологии набирают популярность, отслеживать их рост и выявлять новые тенденции. Эти данные могут служить основой для принятия решений о внедрении технологий, повышении квалификации и распределении ресурсов.
- Получите доступ к богатой базе знаний по программированию: GitHub — это сокровищница проектов с открытым исходным кодом, примеров кода и решений. Это означает, что на платформе вы можете почерпнуть огромный объем знаний и передового опыта в области программирования. Это полезно для образовательных целей, улучшения навыков программирования и понимания того, как внедряются различные технологии.
- Узнайте больше о совместной разработке: репозитории дают представление о том, как разработчики сотрудничают с помощью запросов на получение заявок, проблем и обсуждений. Собирая эти данные, вы сможете изучить модели совместной работы, которые помогут вам разработать стратегии командной работы, улучшить управление проектами и усовершенствовать процессы разработки программного обеспечения.
GitHub — не единственная облачная платформа для размещения репозиториев git, и существует множество альтернатив. Тем не менее, он остается предпочтительным выбором для парсинга данных, поскольку он:
- Большая база пользователей
- Высокая активность пользователей
- Устоявшаяся репутация
В частности, данные GitHub полезны для отслеживания технологических тенденций, поиска библиотек и фреймворков и улучшения процесса разработки программного обеспечения. Эта информация играет ключевую роль в получении конкурентного преимущества в мире информационных технологий.
Библиотеки и инструменты для парсинга GitHub
Python широко известен как отличный язык для поиска веб-страниц благодаря простому синтаксису, удобству для разработчиков и широкому спектру библиотек. Вот почему это рекомендуемый язык программирования для парсинга GitHub. Узнайте больше в нашем подробном руководстве по , как выполнять парсинг веб-страниц с помощью Python.
Следующий шаг — выбор наиболее подходящих библиотек парсинга из широкого спектра доступных опций. Чтобы принять обоснованное решение, сначала изучите платформу в своем браузере. Откройте DevTools и посмотрите на вызовы AJAX, выполняемые страницами репозитория на GitHub. Вы заметите, что большинство из них можно игнорировать. Фактически, большая часть данных страницы встроена в HTML-документы, возвращаемые сервером.
Это означает, что для выполнения задачи будет достаточно библиотеки для HTTP-запросов к серверу в сочетании с анализатором HTML. Итак, вам следует выбрать:
- Requests: самая популярная клиентская библиотека HTTP в экосистеме Python. Это упрощает процесс отправки HTTP-запросов и обработки соответствующих ответов.
- Beautiful Soup: обширная библиотека синтаксического анализа HTML и XML. Он обеспечивает надежную навигацию по DOM и API извлечения данных для парсинга веб-страниц.
Благодаря Requests и Beautiful Soup вы можете эффективно выполнять парсинг GitHub с помощью Python. Давайте подробнее рассмотрим, как это сделать!
Создайте парсер для репозитория GitHub с помощью Beautiful Soup
Следуйте этому пошаговому руководству и узнайте, как парсить GitHub на Python. Хотите не выполнять весь процесс кодирования и парсинга? Купите вместо этого набор данных Github.
Шаг 1. Настройка проекта Python
Прежде чем начать, убедитесь, что вы соответствуете следующим требованиям:
- Python 3+, установленный на вашем компьютере: загрузите инсталлятор, запустите его и следуйте инструкциям.
- IDE Python на ваш выбор: Visual Studio Code с расширением Python и PyCharm Community Edition — две рекомендуемые IDE.
Теперь у вас есть все необходимое для создания проекта на Python!
Запустите в терминале следующие команды, чтобы создать папку github-scraper и инициализировать ее виртуальной средой Python:
mkdir github-scraper
cd github-scraper
python -m venv env
В Windows выполните следующую команду, чтобы активировать среду:
env\Scripts\activate.ps1
В Linux или macOS выполните:
./env/bin/activate
Затем добавьте файл scraper.py
, содержащий следующую строку в папке проекта:
print('Hello, World!')
Сейчас ваш парсер GitHub печатает только надпись «Привет, мир!» но скоро в нем появится логика извлечения данных из общедоступных репозиториев.
Вы можете запустить скрипт с помощью:
python scraper.py
Если все прошло по плану, в терминале должно быть выведено следующее сообщение:
Hello, World!
Теперь, когда вы знаете, что это работает, откройте папку проекта в вашей любимой Python IDE.
Превосходно! Приготовьтесь написать код на Python.
Шаг 2. Установите библиотеки парсинга
Как упоминалось ранее, Beautiful Soup и Requests помогают выполнять парсинг веб-страниц на GitHub. В активированной виртуальной среде выполните следующую команду, чтобы добавить их в зависимости проекта:
pip install beautifulsoup4 requests
Очистите scraper.py
, а затем импортируйте два пакета, используя следующие строки:
import requestsfrom bs4 import BeautifulSoup
# scraping logic...
Убедитесь, что Python IDE не сообщает об ошибках. Вы можете получить некоторые предупреждения из-за неиспользованного импорта. Не обращайте на них внимания, так как вы собираетесь использовать эти библиотеки парсинга для извлечения данных из репозитория из GitHub!
Шаг 3. Загрузите целевую страницу
Выберите репозиторий GitHub, из которого хотите получить данные. Из этого руководстве вы узнаете, как парсить репозиторий luminati-proxy. Имейте в виду, что подойдет любой другой репозиторий, так как логика парсинга будет такой же.
Вот как выглядит целевая страница в браузере:
Сохраните URL-адрес целевой страницы в переменной:
url = 'https://github.com/luminati-io/luminati-proxy'
Затем загрузите страницу с requests.get():
page = requests.get(url)
За кулисами requests
отправляет запрос HTTP GET на этот URL-адрес и сохраняет ответ, полученный сервером, в переменной page
. Вам следует сосредоточить внимание на текстовом атрибуте. Здесь содержится HTML-документ, связанный с целевой веб-страницей. Убедитесь в этом с помощью простой инструкции print
:
print(page.text)
Запустите парсер, и вы увидите следующее в терминале:
<!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
Шаг 4: анализ HTML-документа
Чтобы проанализировать полученный выше HTML-документ, передайте его в Beautiful Soup:
soup = BeautifulSoup(page.text, 'html.parser')
Конструктор BeautifulSoup ()
принимает два аргумента:
- Строка, содержащая содержимое HTML: здесь хранится в переменной
page.text
. - Парсер, который будет использовать Beautiful Soup: “
html.parser
” — это имя встроенного в Python синтаксического анализатора HTML.
BeautifulSoup()
проанализирует HTML и вернет древовидную структуру, которую можно исследовать. В частности, переменная soup
предоставляет эффективные методы выбора элементов из дерева DOM, такие как:
find()
: возвращает первый HTML-элемент, соответствующий стратегии селектора, переданной в качестве параметра.find_all()
: возвращает список HTML-элементов, соответствующих стратегии выбора ввода.select_one()
: возвращает первый HTML-элемент, соответствующий селектору CSS, переданному в качестве параметра.select()
: возвращает список элементов HTML, соответствующих входному селектору CSS.
Обратите внимание, что эти методы также можно вызвать в одном узле древа. В дополнение к ним объект узла Beautiful Soup также предоставляет:
find_next_sibling()
: возвращает первый HTML-узел в братьях и сестрах элемента, соответствующий заданному селектору CSS.find_next_sibrings()
: возвращает все HTML-узлы в братьях и сестрах элемента, соответствующие селектору CSS, переданному в качестве параметра.
Благодаря этим функциям вы готовы к парсингу GitHub. Давайте посмотрим, как это сделать!
Шаг 5: ознакомьтесь с целевой страницей
Прежде чем приступить к программированию, необходимо выполнить еще один важный шаг. Сбор данных с сайта заключается в выборе интересующих HTML-элементов и извлечении из них данных. Определить эффективную стратегию выбора не всегда просто, и вы должны потратить некоторое время на анализ структуры целевой веб-страницы.
Таким образом, откройте целевую страницу GitHub в браузере и ознакомьтесь с ней. Щелкните правой кнопкой мыши и выберите «Проверить», чтобы открыть DevTools:
Углубившись в HTML-код, вы заметите, что многие элементы сайта не классифицируются уникальными классами или атрибутами. Таким образом, обычно бывает сложно перейти к нужному элементу, и вам, возможно, придется непростым способом найти родственные элементы.
Но не волнуйтесь. Разработка эффективных стратегий выбора для GitHub может оказаться непростой, но и невозможной задачей. Продолжайте просматривать страницу в DevTools, пока не будете готовы ее парсить!
Шаг 6: извлеките данные репозитария
Цель — извлечь полезные данные из репозитория GitHub, такие как звезды, описание, последний коммит и т. д. Итак, вам необходимо инициализировать словарь Python, чтобы отслеживать эти данные. Добавьте в свой код:
repo = {}
Сначала проверьте элемент имени:
Обратите внимание, что оно имеет отличительный атрибут itemprop="name"
. Выберите его и извлеките текстовое содержимое с помощью:
name_html_element = soup.select_one('[itemprop="name"]')name = name_html_element.text.strip()
В узле Beautiful Soup используйте метод get_text ()
для доступа к его текстовому содержимому.
Если вы проверите name_html_element.text
в отладчике, вы увидите:
\nluminati-proxy\n
Текстовые поля GitHub обычно содержат пробелы и символы новой строки. Избавьтесь от них с помощью функции Python strip ()
.
Прямо под названием репозитария находится селектор веток:
Обратите внимание, что нет простого способа выбрать HTML-элемент, в котором хранится имя основной ветки. Вы можете выбрать узел .octicon-git-branch
, а затем найти целевой узел span
в его братьях и сестрах:
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()
Шаблон передачи интересующего элемента через родственные элементы иконки довольно эффективен на GitHub. В этом разделе вы увидите, что он использовался несколько раз.
Теперь сосредоточьтесь на заголовке ветки:
Извлеките время последнего коммита с помощью:
relative_time_html_element = boxheader_html_element.select_one('relative-time')
latest_commit = relative_time_html_element['datetime']
При наличии узла вы можете получить доступ к его атрибутам HTML, как в словаре Python.
Еще одна важная информация в этом разделе — количество коммитов:
Соберите его с помощью шаблона значков, описанного выше:
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(',', '')
Обратите внимание, что find_next_sibling ()
предоставляет доступ только братьям и сестрам высшего уровня. Чтобы выбрать одного из их дочерних элементов, вы должны сначала получить родственный элемент, а затем вызвать select_one()
, как описано выше.
Поскольку числа, превышающие тысячу, содержат запятую в GitHub, удалите ее с помощью метода Python replace()
.
Затем обратите внимание на информационное поле справа:
Выберите его с помощью:
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(',', '')
Отлично! Вы только что скопировали репозиторий GitHub.
Шаг 7: выполните парсинг readme
Еще одна важная информация, которую необходимо извлечь, — это файл README.md
. Это дополнительный текстовый файл, в котором описывается репозиторий GitHub и объясняется, как использовать код.
Если вы нажмете на файл README.md
, а затем на кнопку «Raw», вы будете перенаправлены на следующий URL-адрес:
https://raw.githubusercontent.com/luminati-io/luminati-proxy/master/README.md
Таким образом, можно сделать вывод, что URL-адрес файла readme репозитория GitHub соответствует следующему формату:
https://raw.githubusercontent.com/<repo_id>/<repo_main_branch>/README.md
Поскольку информация <repo_main_branch>
хранится в переменной main_branch
, вы можете программно создать этот URL-адрес с помощью f-строки Python:
readme_url = f'https://raw.githubusercontent.com/luminati-io/luminati-proxy/{main_branch}/README.md'
Затем используйте requests
для получения необработанного содержимого Markdown 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
Обратите внимание на проверку 404, чтобы не сохранять содержимое страницы GitHub 404, если в репозитории нет файла readme.
Шаг 8. Сохраните данные парсинга
Не забудьте добавить переменные данных, полученные при парсинге, в словарь 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
Используйте print(repo)
, чтобы убедиться, что процесс извлечения данных работает должным образом. Запустите парсер Python GitHub, и вы получите:
{'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...)'}
Превосходно! Теперь вы знаете, как парсить GitHub!
Шаг 9. Экспортируйте данных парсинга в JSON
Последний шаг — упростить обмен, чтение и анализ собранных данных. Лучший способ добиться этого — экспортировать данные в удобном для восприятия формате, например JSON:
import json
# ...
with open('repo.json', 'w') as file:
json.dump(repo, file, indent=4)
Импортируйте json
из стандартной библиотеки Python, инициализируйте файл repo.json
с помощью open()
и, наконец, используйте json.ump()
для его заполнения. Ознакомьтесь с нашим руководством, чтобы узнать больше о том, как парсить JSON в Python.
Великолепно! Пришло время взглянуть на весь парсер GitHub Python.
Шаг 10. Соберите все вместе
Вот как выглядит полный файл 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)
Менее чем за 100 строк кода вы можете создать веб-паука для сбора данных репозитария.
Запустите скрипт следующим образом:
python scraper.py
Дождитесь завершения процесса парсинга, и вы найдете файл repo.json
в корневой папке своего проекта. Откройте его, и вы увидите:
{
"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..."
}
Поздравляем! Вы начали с необработанных данных, содержащихся на веб-странице, и теперь у вас есть полуструктурированные данные в файле JSON. Вы только что узнали, как создать парсер репозитория GitHub на Python!
Заключение
Это пошаговое руководство помогло вам понять, почему вам следует создать парсер репозитория GitHub. В частности, вы узнали, как парсить GitHub из пошагового руководства. Как показано здесь, требуется всего несколько строк кода.
В то же время все больше и больше объектов внедряют технологии защиты от парсинга. Они могут идентифицировать и блокировать запросы с помощью блокировки IP-адресов и ограничения скорости, предотвращая доступ вашего парсера к сайту. Лучший способ избежать их — прокси-сервер. Ознакомьтесь с обширным предложением Bright Data: первоклассных прокси-сервисов и выделенных прокси-серверов GitHub.
Bright Data контролирует лучшие прокси для веб-парсинга, обслуживая компании из списка Fortune 500 и более 20 000 клиентов. Всемирная прокси-сеть компании включает в себя:
- Прокси-серверы центров обработки данных: более 770 000 IP-адресов центров обработки данных.
- Резидентные прокси — более 72 млн резидентных IP-адресов в более чем 195 странах.
- Прокси-серверы интернет-провайдеров: более 700 000 IP-адресов интернет-провайдеров.
- Мобильные прокси— более 7 млн мобильных IP-адресов.
В целом, Bright Data — это одна из крупнейших и самых надежных на рынке прокси-сетей, ориентированных на парсинг. Поговорите с одним из наших торговых представителей и узнайте, какой из продуктов Bright Data лучше всего соответствует вашим потребностям.
Кредитная карта не требуется
Примечание: на момент написания статьи это руководство было тщательно протестировано нашей командой, но поскольку веб-сайты часто обновляют свой код и структуру, некоторые шаги могут перестать работать должным образом.