Scrape github with python cover

如果您想知道开发人员在哪里交流、协作并获得支持,GitHub就是答案。无论您是独立开发者,还是在全球科技公司任职,它都是获取技术数据的重要平台。GitHub提供功能完善的官方API,在多数情况下应优先使用它。不过,当API无法提供所需数据时,网络抓取也是一种实用的替代方案。  

本教程适合希望进一步了解GitHub、其核心概念,以及如何抓取热门存储库的读者。  

*网络抓取应始终在合法合规且符合道德的范围内进行。我们不鼓励任何非法活动,只倡导负责任地使用相关技术。

I am raw html block.
Click edit button to change this html

什么是GitHub,它如何运作

GitHub已成为全球开发者的重要平台。它可用于托管代码、协作开发项目和构建软件。其名称源自 Git,这正是GitHub所基于的版本控制系统。它无需您保存多个文件版本,因为Git会在同一位置保留完整的变更历史。您随时可以查看改了什么、何时修改,以及由谁修改。对于团队协作而言,这非常方便。  

分叉、存储库、星标和分支,这些概念乍听之下可能有些令人困惑。但了解Git的工作方式后,它们就容易理解了。在Git中,存储库存放项目及其历史记录,提交会记录每一次变更,分支支持并行开发,完成的工作则可合并回主项目。下图可以帮助您理解这一流程:

我们建议您先了解这些术语,相关说明可在其 官方网站

简而言之,该系统使开发人员能够协同工作,而不会覆盖彼此的工作。  

* 抓取GitHub合法吗?

通常来说是合法的,前提是您 遵守其服务条款 并尊重版权和隐私规则。在不违法的前提下,您可以访问公开存储库、用户资料和元数据,例如星标、分叉和提交记录。  

不过,访问私有存储库、敏感用户信息,或进行违反GitHub速率限制的自动化访问,可能导致账号被暂停或产生法律后果。请始终以合乎道德的方式进行抓取,尊重用户隐私,并避免给GitHub服务器造成过高负载。

GitHub如何处理抓取和滥用?

与许多主要平台一样,GitHub采用严格的速率限制以保持稳定性并防止自动滥用。每个API令牌或已验证账号每小时的请求配额都是固定的,通常约为5,000次。达到速率限制通常会返回 403 Forbidden 响应。若同时存在滥用行为,用户的账号可能被暂时或永久停用。为应对持续的机器人访问,GitHub会监测异常流量模式、IP突发请求和重复的身份验证失败。

为了收集数据并将请求量控制在可接受范围内,开发人员可以使用代理作为额外保障。代理可在请求之间轮换源IP地址,并在不同端点间分配流量,从而降低触发GitHub反滥用系统的概率。如果不确定该选择哪类代理,请考虑抓取规模和数据敏感性等因素。 DataImpulse代理 价格合理,并以出色的可靠性和速度著称。我们建议在不违反平台规则的前提下,以负责任且合乎道德的方式使用代理。

尊重GitHub的API规则,避免抓取私有存储库或敏感用户数据。

初始设置:需要下载什么?  

  • Python3(最新版本)

下载: 这里,然后在VS Code中安装Python扩展。打开终端,检查Python是否已安装:  


python3 --version 
      
        
      

  • Visual Studio Code(或其他代码编辑器,最新版本)

下载: 这里,安装后打开您的项目文件夹。

  • 来自DataImpulse仪表板的代理凭证

登录DataImpulse,复制代理的登录凭据。

  • 库:Requests 和 BeautifulSoup;sys 和 typing(Python内置模块)。

Requests:用于发送 HTTP 请求。

BeautifulSoup:用于解析HTML,并从GitHub热门页面提取数据。

sys:用于在出现问题时停止程序并显示错误信息 (sys.exit(…))。

typing:用于提供类型提示,指明各函数预期的数据类型。

首先,在电脑上打开终端,并安装 pip


python3 -m ensurepip 
      
        
      

然后,使用以下命令安装Python库:


pip3 install requests beautifulsoup4 
      
        
      

按下回车键后,即可确认它们是否已安装。

Python中抓取GitHub的常见步骤

  1. 选择目标页面 – 决定您要收集哪个GitHub页面或存储库数据(例如,趋势存储库、用户配置文件)。
  2. 检查 HTML 结构 – 检查页面的 HTML 以识别包含所需数据的元素。
  3. 发送 HTTP 请求 – 使用 Requests 等库获取页面内容。
  4. 解析响应 – 使用 BeautifulSoup 来处理 HTML。
  5. 提取所需数据 – 识别并提取您需要的具体信息。
  6. 处理分页 – 循环浏览页面以提取所有可用条目。  
  7. 存储结果 – 将收集的数据保存在 CSV、JSON或数据库中(可选)。

实际示例:  

在本抓取示例中,我们使用了以下 趋势存储库 页面。在给出完整代码之前,先简要介绍其主要组成部分。

  • 代理配置

代理:来自DataImpulse仪表板的代理凭据(主机、端口、用户名、密码)。将这些值替换为您自己的凭据。
超时:最长请求等待时间(20秒)。
SSL验证:确保HTTPS连接安全。
USER_AGENT:模拟真实浏览器,以通过基础的机器人检测。

  •  GitHub趋势过滤器

LANGUAGE:指定编程语言(可设为 None 以获取全部结果)。
SINCE:时间范围,可选 daily、weekly 或 monthly。


TIMEOUT = 20               # seconds
VERIFY_SSL = True

USER_AGENT = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/118.0.0.0 Safari/537.36"
      
        
   
   
   
   
   
   
      

下面是可以直接尝试的简易代码:  


import requests
from bs4 import BeautifulSoup

LANGUAGE = "python"      # Programming language. None can be used as "Any" parameter in GitHub Trending
SINCE = "daily"          # Date range: daily / weekly / monthly
PROXY = {
    "host": "DATAIMPULSE HOST",
    "port": "DATAIMPULSE PORT",
    "user": "DATAIMPULSE LOGIN",
    "pass": "DATAIMPULSE PASSWORD",
}

# Proxy configuration
proxy_url = f"http://{PROXY['user']}:{PROXY['pass']}@{PROXY['host']}:{PROXY['port']}"
proxies = {
    "http": proxy_url,
    "https": proxy_url,
}
# Checking proxies
ip = requests.get("https://api.ipify.org", proxies=proxies).text
print("Your IP:", ip)
# Scraping Github Trending section 
url = "https://github.com/trending"
# Adding parameters like Language and Date Range, and make HTTP request to GitHub
params = {"since": SINCE}
if LANGUAGE:
    params["language"] = LANGUAGE
headers = {
    "User-Agent": "Mozilla/5.0"
}

r = requests.get(
    url,
    headers=headers,
    params=params,
    proxies=proxies,
    timeout=20
)

# Scrape and output details
soup = BeautifulSoup(r.text, "html.parser")

print("\n🔥 GitHub Trending:\n")
for count, repo in enumerate(soup.select("article.Box-row"), start=1):
    name = repo.h2.text.strip().replace("\n", "").replace(" ", "")
    link = "https://github.com" + repo.h2.a["href"]
    desc = repo.p.text.strip() if repo.p else "No description"
    stars_today = repo.select_one("span.d-inline-block.float-sm-right").text.strip() if repo.select_one("span.d-inline-block.float-sm-right") else None
    print(f"{count}. {name}")
    print(f"Link: {link}")
    print(f"Stars Today: {stars_today}")
    print(f"Description: {desc}")
    print("-" * 40)
      
        
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
      

下一段代码会使用函数。函数可让代码更清晰、更易复用,也更便于调试和维护,尤其适合抓取GitHub或管理多个代理等复杂任务。

  • 函数  

log:格式化控制台输出。
build_proxies:构建代理字符串 (用户名:密码@主机:端口).
test_proxy:通过代理访问 https://api.ipify.org?format=json.
scrape_github_trending:使用 BeautifulSoup4 解析HTML。
main:启动抓取流程。

以下是完整代码:  


import sys
import requests
from bs4 import BeautifulSoup
from typing import List, Dict, Optional
# =========================================================
# CONFIG — CHANGE ONLY THIS SECTION
# =========================================================
GITHUB_TRENDING_URL = "https://github.com/trending"
# Proxy configuration (leave PROXY = None to disable proxy)
PROXY = {
    "host": "DATAIMPULSE HOST",
    "port": "DATAIMPULSE PORT",
    "username": "DATAIMPULSE LOGIN",
    "password": "DATAIMPULSE PASSWORD",
}
# PROXY = None  # uncomment to disable proxy completely

LANGUAGE = "python"        # e.g. "python", "javascript", or None
SINCE = "daily"            # "daily", "weekly", "monthly"
TIMEOUT = 20               # seconds
VERIFY_SSL = True

USER_AGENT = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/118.0.0.0 Safari/537.36"
)

# =========================================================
# END CONFIG
# =========================================================
def log(msg: str) -> None:
    print(f"[INFO] {msg}")

def build_proxies(proxy_cfg: Optional[Dict]) -> Optional[Dict[str, str]]:
    if not proxy_cfg:
        return None

    proxy_url = (
        f"http://{proxy_cfg['username']}:{proxy_cfg['password']}"
        f"@{proxy_cfg['host']}:{proxy_cfg['port']}"
    )

    return {
        "http": proxy_url,
        "https": proxy_url,
    }

def test_proxy(proxies: Optional[Dict[str, str]]) -> None:
    log("Testing proxy...")
    r = requests.get(
        "https://api.ipify.org?format=json",
        proxies=proxies,
        timeout=10,
    )
    r.raise_for_status()
    log(f"Proxy OK. Outgoing IP: {r.json()['ip']}")

def scrape_github_trending(
    language: Optional[str],
    since: str,
    proxies: Optional[Dict[str, str]],
    timeout: int,
) -> List[Dict]:
    headers = {"User-Agent": USER_AGENT}

    params = {"since": since}
    if language:
        params["language"] = language

    log("Fetching GitHub Trending page...")
    response = requests.get(
        GITHUB_TRENDING_URL,
        headers=headers,
        params=params,
        proxies=proxies,
        timeout=timeout,
        verify=VERIFY_SSL,
    )
    response.raise_for_status()

    soup = BeautifulSoup(response.text, "lxml")
    repos = []

    for article in soup.select("article.Box-row"):
        name = (
            article.h2.text
            .replace("\n", "")
            .replace(" ", "")
            .strip()
        )
        url = "https://github.com" + article.h2.a["href"]

        description = article.p.text.strip() if article.p else None

        language_el = article.select_one(
            '[itemprop="programmingLanguage"]'
        )
        stars_today_el = article.select_one(
            "span.d-inline-block.float-sm-right"
        )

        repos.append({
            "name": name,
            "url": url,
            "description": description,
            "language": (
                language_el.text.strip()
                if language_el else None
            ),
            "stars_today": (
                stars_today_el.text.strip()
                if stars_today_el else None
            ),
        })

    return repos

def main() -> None:
    proxies = build_proxies(PROXY)

    # 1) Test proxy
    try:
        if proxies:
            test_proxy(proxies)
        else:
            log("Proxy disabled.")
    except Exception as e:
        sys.exit(f"[ERROR] Proxy test failed: {e}")

    # 2) Scrape GitHub Trending
    try:
        repos = scrape_github_trending(
            language=LANGUAGE,
            since=SINCE,
            proxies=proxies,
            timeout=TIMEOUT,
        )
    except Exception as e:
        sys.exit(f"[ERROR] Scraping failed: {e}")

    # 3) Output
    print("\n🔥 GitHub Trending Repositories\n")
    print(f"Language: {LANGUAGE or 'All'} | Since: {SINCE}\n")

    for i, repo in enumerate(repos, 1):
        print(f"{i}. {repo['name']}")
        print(f"   URL: {repo['url']}")
        print(f"   Language: {repo['language']}")
        print(f"   Stars today: {repo['stars_today']}")
        if repo["description"]:
            print(f"   Description: {repo['description']}")
        print()

    log(f"Done. Total repositories: {len(repos)}")

if __name__ == "__main__":
    main()
      
        
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
      

运行后,终端会显示包含14个热门存储库的清晰列表。

总结与建议

抓取GitHub是一项实用技能,但同样需要遵守道德规范和技术要求。初学者也可以从Gemini Bot入手,无需编写代码即可提取结构化数据。只需创建一个机器人,并输入如下提示:  

分析此GitHub存储库页面并提取以下信息:

– 存储库名称

– 星标数量

– 主要编程语言

– 最后一次提交的日期

返回JSON格式的数据。

以上就是基本流程。我们也鼓励开发人员尝试新思路、组合不同工具,并根据项目需求调整方法。使用代理时,请始终遵守GitHub服务条款;利用筛选条件定位特定语言或热门周期;记录并监控请求;先从少量存储库开始,再逐步扩大规模。

Share article: