Skip to main content

requests-rs

浏览器级网络指纹,Rust 级传输性能,requests 级开发体验。

为高并发采集、自动化、代理网络与传输研究打造的 Python 原生 HTTP 客户端。

PyPI Python 3.10+ Rust HTTP Async License

逐请求 DNS · 指纹运行时加载 · wheel 内置根证书 · Rust 原生并发背压


requests-rs 把 DNS、TCP、TLS、HTTP/1.1、HTTP/2、HTTP/3、代理、Cookie、连接池、流式响应和 WebSocket 全部压进 Rust 网络核心,再通过 PyO3 提供接近 requests 的同步与原生异步 API。

它不是给 requests 套一层线程池,也不是换个 User-Agent 冒充浏览器。请求直接进入共享 Tokio Runtime,BoringSSL 与真实浏览器采集画像负责 TLS/H2/H3 回放,Python 只保留清晰的调用接口和结果消费。

一句话: 想要 requests 的易用性、浏览器的网络画像、Rust 的高并发执行与可控资源边界,就用 requests-rs。

核心能力

能力 requests-rs 提供什么
Rust 原生网络核心 网络等待不占用 Python 工作线程;DNS、连接、TLS、代理握手、重定向、Body 读写和 Cookie 更新由 Rust/Tokio 执行。
浏览器级传输画像 回放真实 TLS ClientHello、HTTP/2 SETTINGS、Header 顺序;schema 2 进一步覆盖 QUIC Transport Parameters、HTTP/3 SETTINGS 与 QPACK。
DNS 深度可控 TCP 请求支持 Session 级和单请求级 dns_servers、查询超时、A/AAAA、TTL 缓存、UDP 查询与 TCP 回退,并提供 resolve 静态域名/IP绑定。
动态加载指纹 Session 构造时可直接加载 JSON 路径、Python 记录列表或 {schema_version, records} 对象,不必重新编译 wheel。
内置根证书库 wheel 内置并显式注入 Mozilla/WebPKI 根证书,不依赖机器上残缺、过期或配置混乱的系统 CA 环境。
原生并发信号量 HTTP、代理请求、流、multipart 与 WebSocket 共用一个 Rust/Tokio Semaphore,并发上限在网络核心内执行。
连接与身份隔离 Origin、代理身份、DNS配置和指纹变体共同决定连接复用边界;切换代理时同步清理连接池和 TLS ticket 状态。
同步与异步统一 Session、AsyncSession、模块级方法、响应对象、Cookie 与错误边界保持一致。

为什么更适合高并发

请求直接进入 Rust,不绕 Python 线程池

传统 requests 是同步模型。要在 asyncio 项目中并发使用,通常需要 asyncio.to_thread() 或 ThreadPoolExecutor:每个正在等待网络的请求都会占用或等待 Python 工作线程。

requests-rs 的 AsyncSession 暴露原生 awaitable,请求直接进入共享 Tokio Runtime:

Python coroutine
      │
      ▼
PyO3 native Future
      │
      ▼
Tokio Runtime ── DNS / TCP / TLS / HTTP / Proxy / Cookie / Stream
      │
      ▼
wreq + BoringSSL + quiche

这意味着高并发网络等待不需要创建同等数量的 Python 工作线程,减少线程池排队、线程栈、上下文切换和 GIL 周边调度开销。相比“同步 requests + 线程池”的并发方式,任务越多,这个架构优势越明显。

对 httpx、aiohttp、curl_cffi 等已经具备异步或原生后端的客户端,实际吞吐仍取决于目标站、TLS、代理、响应大小、连接复用与机器配置;requests-rs 的优势在于把浏览器指纹、DNS、代理、Cookie、连接池和资源背压统一收进同一个 Rust Session。

原生信号量,更短调度路径,更快进入网络核心

max_connections 不是 Python 外层装饰器,而是 Rust/Tokio 原生 Semaphore。请求不需要先经过 Python 锁、许可队列或释放回调,再转交底层客户端;并发许可直接在网络核心入口获取,调度路径更短,取消和释放也由同一所有权模型收口:

  • 请求进入网络核心前原子获取许可;
  • 等待许可不会阻塞 Python 事件循环;
  • 等待时间计入请求总超时;
  • 普通响应读取完成后自动释放;
  • 流式响应持有许可到 EOF 或关闭;
  • WebSocket 持有许可到真实连接终止;
  • 取消 Future 会自动释放尚未移交的许可;
  • Session 关闭会唤醒全部等待任务并快速失败。

HTTP、HTTPS、HTTP 代理、SOCKS5、流、multipart 和 WebSocket 共享同一个并发池,不会出现“HTTP 50 个 + WebSocket 50 个 + 下载 50 个”分别突破上限的隐形资源膨胀。

import asyncio
from requests_rs import requests


async def main() -> None:
    urls = [f"https://example.com/?id={index}" for index in range(1000)]

    async with requests.AsyncSession(
        impersonate="chrome152",
        max_connections=100,
        timeout=30,
    ) as session:
        responses = await asyncio.gather(*(session.get(url) for url in urls))

    print(len(responses))


asyncio.run(main())

在仓库的极端回归中,max_connections=1 被长流占用时,1000 个等待任务没有膨胀成 1000 个 Python 线程;测试门槛限制 RSS 增量小于 32 MiB、线程增量不超过 4。该数据用于同环境回归,不是跨机器固定承诺,但验证了当前实现不是 worker-per-request,而是共享异步原语管理的大规模等待队列。

30 秒开始

安装

python -m pip install -U requests-rs

当前 wheel 使用 CPython Stable ABI,支持 CPython 3.10 及以上版本。PyPI 已提供 Windows x64 与 manylinux2014 x64 wheel;其他平台请查看下方支持矩阵或从源码构建。

唯一公开导入入口:

from requests_rs import requests

同步请求

from requests_rs import requests

with requests.Session(
    impersonate="chrome152",
    timeout=30,
) as session:
    response = session.get("https://example.com/")
    response.raise_for_status()

    print(response.status_code)
    print(response.http_version)
    print(response.fingerprint_id)
    print(response.text)

原生异步请求

import asyncio
from requests_rs import requests


async def main() -> None:
    async with requests.AsyncSession(
        impersonate="edge152",
        max_connections=50,
    ) as session:
        first, second = await asyncio.gather(
            session.get("https://example.com/api/one"),
            session.post("https://example.com/api/two", json={"id": 2}),
        )
        print(first.status_code, second.status_code)


asyncio.run(main())

DNS 可改,而且可以逐请求切换

requests-rs 不把 DNS 锁死在操作系统配置里。你可以在 Session 级指定长期上游,也可以为某一次请求临时切换解析器。

Session 级自定义 DNS

from requests_rs import requests

with requests.Session(
    impersonate="chrome152",
    dns_servers=["1.1.1.1", "8.8.8.8"],
    dns_timeout=3.0,
) as session:
    response = session.get("https://example.com/")

底层使用 Rust Hickory Resolver,支持:

  • IPv4、IPv6 与自定义端口,例如 127.0.0.1:5353、[::1]:5353;
  • A/AAAA 双栈查询;
  • DNS TTL 缓存;
  • UDP 查询失败或截断后的 TCP 回退;
  • 多个上游 DNS;
  • Session 关闭或代理切换时清理关联 Client 与缓存。

单请求覆盖 DNS

response = await session.get(
    "https://example.com/",
    dns_servers=["9.9.9.9", "149.112.112.112"],
    dns_timeout=2.0,
)

这只影响当前请求,不修改 Session 默认值,也不污染其他并发任务。默认启用 fingerprint_pool 时,相同请求级配置会进入按指纹隔离的有界 Rust Client 缓存,可继续复用 Resolver TTL、TCP、TLS 与 HTTP/2 连接。

传入空列表可让单次请求临时恢复系统 DNS:

response = await session.get(url, dns_servers=[])

固定连接 IP,同时保留 HTTPS 域名语义

resolve 适合固定 CDN 节点、测试指定 IP 或绕过错误 DNS 答案:

async with requests.AsyncSession(
    impersonate="chrome152",
    resolve={
        "example.com": ["203.0.113.10", "2001:db8::10"],
    },
) as session:
    response = await session.get("https://example.com/")

实际连接使用指定 IP,但 URL、HTTP Host、TLS SNI 与证书域名仍然保持 example.com。这比直接请求 IP 再手写 Host 更完整,也不会为了固定节点而牺牲 HTTPS 校验。

HTTP/3 提示: dns_servers 当前作用于 TCP HTTP 路径,因此配置后会安全使用 H2/H1.1;需要固定 QUIC/H3 目标地址时使用 Session 级 resolve。最终协议始终以 response.http_version 为准。

指纹不必写死,运行时动态加载

内置 profile 适合开箱即用,自定义 profile 则可以在创建 Session 时动态加载。无需修改 Rust 源码,无需重编 wheel,也不会污染进程级内置指纹缓存。

直接加载单 profile JSON

from pathlib import Path
from requests_rs import requests

fingerprint_file = Path(r"C:\fingerprints\edge152.json")

with requests.Session(
    impersonate=fingerprint_file,
    fingerprint_rotation=False,
) as session:
    response = session.get("https://example.com/")
    print(session.impersonate)
    print(session.fingerprint_count)
    print(response.fingerprint_id)

捕获结果不落盘,直接从内存加载

capture_result = await mcp_client.call_tool(
    "read_fingerprint_result",
    {"task_id": task_id},
)

async with requests.AsyncSession(
    impersonate=capture_result,
    fingerprint_rotation=False,
) as session:
    response = await session.get("https://example.com/")

impersonate 支持:

  • 单 profile JSON 文件路径;
  • Python Sequence[Mapping] 指纹记录;
  • 捕获器/MCP 返回的 {schema_version, records, ...} 对象;
  • 一个 profile 内的多个变体与随机轮换。

多 profile 文件可以通过 fingerprints_path 显式选择:

with requests.Session(
    impersonate="edge152",
    fingerprints_path=r"C:\fingerprints\all_profiles.json",
    fingerprint_rotation=True,
    fingerprint_pool=True,
    fingerprint_pool_size=20,
) as session:
    response = session.get("https://example.com/")

每个 Session 独立拥有自己的自定义指纹。不同实例可以同时加载不同文件,互不覆盖;未知 schema、未知非 GREASE TLS/H2/H3 字段、损坏 payload 或协议字段冲突会在构造阶段 fail-closed,不会悄悄降级成一份看起来成功、实际上已经变形的画像。

动态加载指的是 Session 构造期运行时加载。已创建的 Session 不监视文件变化;需要更新画像时创建新的 Session,可保持生命周期和连接身份边界清晰。

内置根证书,跨环境保持一致的浏览器级信任基线

公开 wheel 内置 Mozilla/WebPKI 根证书集合,并由网络核心显式构建和复用 CertStore。证书信任基线跟随 wheel 交付,不依赖新机器、精简容器或异常系统环境中可能缺失、过期、路径错误的 CA 文件。

实际收益:

  • 减少 CERTIFICATE_VERIFY_FAILED、unable to get local issuer certificate 等由运行环境 CA 不完整造成的问题;
  • Windows 与 Linux 使用一致的公开根信任基线,迁移环境时行为更稳定;
  • HTTP/1.1、HTTP/2 与 HTTP/3 使用同一套明确的证书信任策略;
  • resolve 固定 IP 时仍保持原始 SNI、Host 与证书域名校验;
  • 不需要为了“先跑起来”而全局关闭 HTTPS 验证。

内置根证书解决的是环境型 CA 问题,不会错误放行过期证书、域名不匹配、未知私有 CA 或真正不可信的证书链。根集合随 wheel 版本更新,不自动读取系统企业私有 CA。生产环境应始终保持 verify=True;verify=False 只适用于受控的本地自签名测试。

与常见 Python HTTP 方案相比

维度 requests httpx / aiohttp curl_cffi requests-rs
调用体验 简单同步 原生异步 requests 风格 requests 风格,同步与原生异步统一
asyncio 网络等待 通常需要线程池包装 原生异步 提供异步接口 PyO3 原生 Future 直入 Tokio
浏览器 TLS/H2 画像 无 无 支持 impersonate 真实采集画像,支持动态加载与严格校验
HTTP/3 画像 无 通常无 依构建能力 schema 2 驱动 TLS/QUIC/H3/QPACK 回放
自定义 DNS 依赖外部适配 各库接口不同 能力依后端 Session 级 + 单请求级 + 静态 resolve
并发上限 连接池外通常需业务限流 提供连接池限制,业务操作常另行限流 提供客户端并发参数 一个 Rust Semaphore 统一普通请求、流、multipart 与 WebSocket 的完整许可生命周期
根证书环境 通常依赖 certifi/运行环境配置 通常依赖 certifi/SSL context 取决于构建和系统 根集合随 wheel 固化,由 Rust TLS 核心显式注入,跨环境可复现
代理身份切换 业务自行隔离 业务自行隔离 支持代理 原子快照并清理连接池、TLS ticket 与路由缓存
Python 工作线程 同步并发常依赖线程池 异步模式无需逐请求线程 取决于使用模式 异步请求不按请求占用 Python worker

Rust 并不自动等于任何场景都更快,但 requests-rs 把最重的协议路径和资源调度移出 Python:在高并发、长连接、代理、动态 DNS、流式响应和复杂指纹场景中,可以避免同步 requests 的 Python 线程池成本,也减少业务层重复实现锁、信号量、连接身份隔离和清理逻辑。

仓库提供 benchmark_async_bridge.py、benchmark_async_resources.py 等本地 benchmark,用于在相同机器、相同后端、相同代理、相同并发和相同连接复用条件下对比 native Future、线程池桥接与资源峰值。性能数字会随网络和目标服务显著变化,因此 README 不展示脱离环境的倍数结论。

浏览器画像与协议

内置 Profile

Profile 来源 状态
chrome146 Google Chrome 历史采集 已验证固定快照
chrome150 Google Chrome 历史采集 已验证固定快照
chrome152 Google Chrome 152.0.7977.64 官方正式版基线,Trust Anchor IDs 已完成线级回放
edge152 Microsoft Edge 152.0.4191.53 系统稳定版基线,已完成采集与回放
firefox151 playwright_rust Firefox Juggler 已验证研发兼容快照,不代表 Mozilla 官网 Stable

Profile 是已采集、验证并冻结的传输快照,不是自动追随浏览器官网版本变化的字符串别名。

HTTP/3

http_version="http3" 是完整模板下的 H3 优先策略:

  • 直连 HTTPS 且所选记录为 schema 2 时,应用 BoringSSL ClientHello、QUIC Transport Parameters、HTTP/3 SETTINGS、Header顺序与 QPACK 策略;
  • schema 1、代理、multipart、transfer stats 或自定义 dns_servers 场景安全使用 H2/H1.1;
  • H3 失败时,安全方法可在同一总超时内降级;
  • 请求已经发出后的失败不会自动重放有副作用的业务操作;
  • 只有完整模板实际应用时,响应才会返回对应源 fingerprint_id。

HTTP/3 仍在持续进行独立互操作验证,不应把“请求成功”误认为与任意历史浏览器百分之百线级等价。

连接、代理与资源生命周期

  • 长期复用一个 Session,可以复用匹配 Origin 与代理身份的 TCP、CONNECT、TLS 和 HTTP/2 连接;
  • 每个指纹变体拥有隔离的 Client、TLS session 与请求级 DNS Client 缓存;
  • set_proxy() 通过原子快照切换默认代理,并清理旧 Client、DNS、H3、Origin 与 TLS ticket 状态;
  • max_cached_origins 为高基数域名和代理身份提供有界缓存边界;
  • max_response_bytes 默认限制解压后的响应累计大小,阻止压缩炸弹和并发大 Body 无限吃内存;
  • H1/H2 流式响应支持分块消费,EOF、错误、取消或关闭时释放原生许可;
  • Session 关闭后拒绝新请求,并唤醒正在等待并发槽位的任务。

库不提供业务 batch()、任务重试或常驻业务 Worker 队列。业务层应该用有限任务调用一个长期 AsyncSession,让网络库负责连接、协议和资源背压,让业务代码负责重试策略、配额和数据流程。

支持平台

平台 Rust target wheel 标签 当前发布状态
Windows x64 x86_64-pc-windows-msvc win_amd64 PyPI wheel
Linux x64 x86_64-unknown-linux-gnu manylinux2014_x86_64 PyPI wheel,glibc >= 2.17
Windows ARM64 aarch64-pc-windows-msvc win_arm64 CI 构建与安装验证,暂未发布 PyPI
Linux ARM64 aarch64-unknown-linux-gnu manylinux_2_34_aarch64 PyPI wheel,glibc >= 2.34,原生 ARM64 完整回归通过
macOS Apple Silicon aarch64-apple-darwin macosx_11_0_arm64 CI 构建与安装验证,暂未发布 PyPI

Alpine musl 与 macOS Intel 当前不在公开发布矩阵中。安装时必须选择与操作系统和 CPU 匹配的 wheel。

示例与文档

从源码构建

需要 Rust stable、Python 3.10+、maturin、CMake、Clang/libclang 与平台原生 C/C++ 工具链:

git clone https://github.com/zt1901/requests-rs.git
cd requests-rs
python -m pip install "maturin>=1.9,<2"
maturin build --release --out dist
python -m pip install --force-reinstall dist/requests_rs-*.whl

Windows 也可直接运行 build_and_install.py。脚本默认使用仓库内置指纹完成构建;只有显式传入 --sync-fingerprints 时才从本机来源同步指纹。

使用边界

  • requests_rs.requests 兼容 curl_cffi.requests 的高频命名,但不承诺兼容全部专有参数;未知关键参数会明确失败。
  • 业务 Cookie、认证、CSRF、签名、时间戳和 nonce 不属于浏览器传输画像,应通过 headers、cookies、data 或 json 传入。
  • verify=False 只适用于受控测试,不应作为解决生产证书问题的方案。
  • 指纹动态加载发生在 Session 构造阶段,不是已创建 Session 的文件热重载。
  • max_connections 限制活跃网络操作,不等价于严格的物理 TCP/QUIC 连接总数。
  • H1/H2 stream=True 是增量读取;当前 H3 路径仍先完成响应接收,再提供统一的消费接口。
  • 性能比较必须固定机器、版本、后端、代理、并发、连接复用和响应大小;不要把本地请求/秒直接外推到公网。

贡献

欢迎提交问题和改进。网络能力变更应覆盖同步/异步生命周期、取消、关闭、错误与资源释放;指纹变更应附浏览器版本、真实采集记录和线级对照证据。

许可证

项目原创代码采用 MIT 或 Apache-2.0 双许可证,使用者可任选其一。Vendored 第三方组件继续遵循各自许可证与 NOTICE。

Metadata

Release files for requests-rs 0.4.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for requests-rs 0.4.4
File Interpreter ABI Platform
requests_rs-0.4.4-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
requests_rs-0.4.4-cp310-abi3-manylinux_2_34_x86_64.whl CPython 3.10 abi3 Linux glibc 2.34+ x86-64 Details
requests_rs-0.4.4-cp310-abi3-manylinux_2_34_aarch64.whl CPython 3.10 abi3 Linux glibc 2.34+ ARM64 Details

Total release size: 14.4 MB

Release files / requests_rs-0.4.4-cp310-abi3-win_amd64.whl

Download URL requests_rs-0.4.4-cp310-abi3-win_amd64.whl
Size 5.1 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
420ab2a5025e5c1c8975335823e30194abcfc1e7365998e5d94a2b030278c663
BLAKE2b-256 checksum
How to use checksums
eed8e395792df0ee2ff60f0ee18591513801cd5bc1001b27068b199984418405
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / requests_rs-0.4.4-cp310-abi3-manylinux_2_34_x86_64.whl

Download URL requests_rs-0.4.4-cp310-abi3-manylinux_2_34_x86_64.whl
Size 4.8 MB
Tags CPython 3.10 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
a73fb0cad0aeb704a7f3c094b95a23b810f8e58c2db96eda9457e8d93435d5e0
BLAKE2b-256 checksum
How to use checksums
98169391b0864b31162473d94056a4ca51a8b5cfda895e0e5af7a2d4c99e4ce2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / requests_rs-0.4.4-cp310-abi3-manylinux_2_34_aarch64.whl

Download URL requests_rs-0.4.4-cp310-abi3-manylinux_2_34_aarch64.whl
Size 4.6 MB
Tags CPython 3.10 Linux glibc 2.34+ ARM64 abi3
SHA-256 checksum
How to use checksums
050d8de0a0ee90f971c585f4b889884335f919b27d416aca27af033dcd2c2fa6
BLAKE2b-256 checksum
How to use checksums
97551b2cbdb49ed1d5ad642aed1aba284e02370e211642dc2b67c11ef3f80a68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

0.4.10

5 release files

This release

0.4.4 This release

3 release files

0.4.3

3 release files

0.4.2

3 release files

0.4.1

2 release files

0.3.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page