이 글에서는 Python을 사용하여 GitHub 리포지토리를 스크래핑하는 방법을 분석해 보겠습니다. BeautifulSoup, Requests와 같은 잘 알려진 라이브러리를 검토하고 쉽게 따라할 수 있도록 스크래핑 GitHub 스크립트를 작성하면서 자세한 설명을 제공합니다.
깃허브 스크래핑이란 무엇이며 어떤 용도로 사용하나요? 다양한 용도로 사용할 수 있지만 가장 자주 사용하는 용도는 다음과 같습니다:
GitHub는 리포지토리 호스팅을 제공할 뿐만 아니라 방대한 사용자 기반을 보유하고 있으며, 평판이 좋아 신뢰할 수 있는 옵션입니다.
GitHub에 저장된 정보는 기술 발전의 패턴을 추적하고 소프트웨어 개발을 개선하는 데 유용합니다. 이러한 정보는 정보 기술 분야의 경쟁자를 따라잡는 데 매우 중요합니다.
웹 페이지를 스크랩할 때 가장 쉽게 작업할 수 있는 언어는 라이브러리와 모듈이 매우 많은 Python입니다. Python을 Github 스크래핑하려면 다음 모듈을 추가해야 합니다:
이 작업은 깃허브 스크래핑 도구를 사용하면 매우 쉽게 수행할 수 있습니다. 하지만 그 방법을 자세히 설명해 드리겠습니다.
이 파트에서는 Github 리포지토리를 스크레이핑하는 방법을 설명합니다. 스크레이퍼를 만드는 데 있어 중요한 단계는 다음과 같습니다:
지금부터 이 모든 단계에 대한 자세한 내용과 함께 완성된 스크래핑 Github 스크립트를 공유하겠습니다.
컴퓨터에 Python이 설치되어 있는지 확인합니다. 그런 다음 Github 스크래핑 프로세스를 시작하기 위한 새로운 Python 가상 환경을 만듭니다.
python -m venv github_scraper
source github_scraper/bin/activate # MacOS 및 Linux용
github_scraper\Scripts\activate # Windows용
앞서 말했듯이 BeautifulSoup과 Requests는 GitHub 리포지토리를 스크랩하는 데 도움이 됩니다. 현재 활성화된 가상 환경에서 이 명령을 실행하여 프로젝트 종속 요소에 포함하세요:
pip install beautifulsoup4 requests
Github 스크래핑을 수행하려는 리포지토리를 선택합니다. 먼저 변수에 링크를 정의한 다음 페이지 코드를 가져올 HTTP 요청을 합니다.
url = "https://github.com/TheKevJames/coveralls-python"
response = requests.get(url)
HTML을 분석하려면 BeautifulSoup에 입력합니다.
soup = BeautifulSoup(page.text, 'html.parser')
BeautifulSoup() 생성자에는 두 가지를 제공해야 합니다.
HTML은 BeautifulSoup에 의해 파싱되고 트리 구조가 생성됩니다. 보다 구체적으로, soup 변수에는 다음과 같이 DOM 트리에서 관련 요소를 선택하는 데 필요한 모든 메서드가 포함되어 있습니다:
또 다른 중요한 단계는 간단한 HTML 요소를 선택하고 이 요소에서 Github 데이터를 스크랩하는 것입니다. 이 단계는 실제로 Python Github 리포지토리 스크립트를 작성하기 전에 선행되는 단계입니다.
깃허브를 스크랩하기 전에 웹페이지 자체에 익숙해지세요. 그런 다음 F12를 클릭하여 개발자 도구를 엽니다. 이제 코드를 열었으므로 페이지의 많은 요소에 고유한 클래스나 속성이 없어 적절한 요소로 쉽게 이동할 수 있는 것을 알 수 있습니다. 페이지를 살펴보고 데이터 추출을 준비합니다.
이제 GitHub 리포지토리를 스크랩하는 데 도움이 될 Python 스크립트를 만들 준비가 되었습니다. 이 스크립트는 별, 설명, 마지막 커밋 등과 같이 GitHub에 저장된 유용한 정보를 추출할 수 있습니다. 이를 위해서는 필요한 기능을 지정하고 해당 텍스트 값을 검색해야 합니다.
repo_title = soup.select_one('[itemprop="name"]').text.strip()
itemprop="name" 속성은 고유한 ID를 가진 속성 값을 가지고 있으므로 이를 검색합니다. 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']
사용자의 마지막 커밋이 저장된 상대 시간 태그가 이미 선택되어 있고 날짜는 날짜 시간을 통해 선택되었다는 점에 주목했습니다.
왼쪽에 있는 정보(설명, 별, 조회수, 포크)를 수집합니다.
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(',', '')
README 파일은 매우 중요합니다. 리포지토리에 대한 설명과 코드를 구현하는 방법에 대한 지침을 제공합니다. readme.md 파일을 확인하면 어떤 링크가 있는지 알 수 있습니다:
https://raw.githubusercontent.com///readme.md
가 있으므로 f- 문자열을 사용하여 프로그래밍 방식으로 URL을 생성하고 이를 사용하여 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 파일이 없는 경우 404 오류가 발생하는지 확인하여 GitHub 404 웹페이지의 콘텐츠가 저장되지 않도록 하세요.
모든 정보는 단일 사전에 저장되므로 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
내장된 Python 라이브러리를 활용하여 데이터를 분석하고 JSON 형식으로 저장할 것인데, 이는 기사 목록이 있는 경우처럼 중첩된 구조에 적합하기 때문입니다.
with open('github_data.json', 'w', encoding='utf-8') as json_file:
json.dump(repo, json_file, ensure_ascii=False, indent=4)
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()
# 지점
main_branch = soup.select_one(
'[class="Box-sc-g0xbh4-0 ffLUq ref-selector-button-text-container"]').text.split()
# 최신 커밋
relative_time_html_element = soup.select_one('relative-time')
latest_commit = relative_time_html_element['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(',', '')
# 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)
지금까지 BeautifulSoup과 Requests의 도움으로 리포지토리에 대한 스크래핑 GitHub 스크립트를 구축하는 과정을 살펴봤습니다. 이제 웹 페이지에 액세스하여 관련 데이터를 가져와서 사용자 친화적인 방식으로 인코딩하는 방법을 알게 되었습니다. 이러한 기술은 잘 알려진 프로젝트를 분석하거나 코드의 변경 사항을 추적하거나 보고서를 생성하는 데 유용할 것입니다.
그럼에도 불구하고 현명한 사용을 위해 주의를 기울이세요. 대부분의 경우 GitHub에서 API를 사용할 수 있으므로 더 간단하고 실용적으로 작업할 수 있습니다. 웹 스크래핑을 수행하기로 결정한 경우 사이트의 가이드라인을 준수하고 너무 많은 요청으로 서버를 폭격하지 않도록 하세요.
댓글: 0