You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过编程获取ArchLinux AUR所有软件包元数据?优先Python实现

嘿,我之前也碰到过这个痛点!AurJson的搜索接口确实要求关键词至少2个字符,没法直接拿到全量包数据,但咱们可以绕个小弯——先获取完整的AUR包名清单,再批量查询它们的元数据。下面是具体的Python实现方案:

实现思路
  • 第一步:获取全量包名:Arch Linux AUR官方提供了一个压缩的包名列表文件,里面每行对应一个AUR包的名称,数据更新及时且可靠。
  • 第二步:批量查询元数据:利用AUR RPC接口的multiinfo类型,支持一次传入多个包名(避免频繁请求触发限流),批量拉取每个包的完整元数据。
准备工作

首先需要安装requests库(用于HTTP请求),执行以下命令:

pip install requests
Python代码实现
import requests
import gzip
from itertools import islice
import time

# AUR官方的包名压缩文件地址
PACKAGES_LIST_URL = "https://aur.archlinux.org/packages.gz"
# AUR RPC接口地址
AUR_RPC_URL = "https://aur.archlinux.org/rpc/?v=5"

def get_all_aur_package_names():
    """从官方压缩文件获取所有AUR包的名称列表"""
    try:
        response = requests.get(PACKAGES_LIST_URL, timeout=10)
        response.raise_for_status()  # 捕获HTTP请求错误
        # 解压gzip格式的响应内容
        with gzip.GzipFile(fileobj=response.raw) as gzip_file:
            content = gzip_file.read().decode("utf-8")
        # 按行分割并过滤空行,得到包名列表
        package_names = [name.strip() for name in content.split("\n") if name.strip()]
        return package_names
    except Exception as e:
        print(f"获取包名列表失败: {str(e)}")
        return []

def batch_fetch_package_metadata(package_names, batch_size=80, request_delay=0.5):
    """
    批量获取包元数据
    :param package_names: 完整的AUR包名列表
    :param batch_size: 每次请求携带的包数量(建议不要超过100,避免触发限流)
    :param request_delay: 批次请求之间的间隔时间(秒,防止被限流)
    """
    package_iter = iter(package_names)
    while True:
        # 按批次截取包名
        current_batch = list(islice(package_iter, batch_size))
        if not current_batch:
            break
        
        # 构造RPC请求参数:使用multiinfo类型,传入当前批次的所有包名
        request_params = {"type": "multiinfo"}
        for idx, pkg_name in enumerate(current_batch):
            request_params[f"arg[{idx}]"] = pkg_name
        
        try:
            response = requests.get(AUR_RPC_URL, params=request_params, timeout=10)
            response.raise_for_status()
            rpc_data = response.json()
            # 迭代返回当前批次的所有包元数据
            yield from rpc_data.get("results", [])
            # 批次之间添加延迟,避免触发限流
            time.sleep(request_delay)
        except Exception as e:
            print(f"批量查询元数据失败: {str(e)}")
            continue

if __name__ == "__main__":
    # 第一步:获取所有AUR包名
    print("正在拉取AUR全量包名列表...")
    aur_package_names = get_all_aur_package_names()
    if not aur_package_names:
        print("未能获取到包名列表,程序退出")
        exit(1)
    print(f"成功获取到 {len(aur_package_names)} 个AUR包的名称")
    
    # 第二步:批量获取元数据并处理
    print("开始批量获取包元数据...")
    processed_count = 0
    # 这里可以根据需求修改处理逻辑,比如保存到JSON文件、数据库等
    for pkg_metadata in batch_fetch_package_metadata(aur_package_names):
        processed_count += 1
        # 示例:打印包的核心信息
        print(f"[{processed_count}] 包名: {pkg_metadata['Name']} | 版本: {pkg_metadata['Version']} | 维护者: {pkg_metadata.get('Maintainer', '无')}")
        
        # 如果需要保存元数据,可以将pkg_metadata添加到列表后写入文件
        # 比如:
        # import json
        # all_metadata.append(pkg_metadata)
        # with open("aur_packages_metadata.json", "w", encoding="utf-8") as f:
        #     json.dump(all_metadata, f, ensure_ascii=False, indent=2)
关键注意事项
  • 限流规避:AUR的RPC接口有请求频率限制,建议将batch_size控制在80-100之间,同时添加request_delay(0.5-1秒)避免触发429限流错误。如果还是遇到限流,可以进一步减小批次大小或延长延迟。
  • 数据字段说明:返回的元数据包含丰富信息,常用字段有Name(包名)、Version(版本)、Description(描述)、Maintainer(维护者)、NumVotes(投票数)、Popularity(流行度)等,可按需提取。
  • 无效包处理:部分包可能已被删除或归档,multiinfo接口会自动过滤这些无效包,因此最终获取到的元数据数量可能略少于初始包名列表的数量。

内容的提问来源于stack exchange,提问作者xuhdev

火山引擎 最新活动