lexiforest/curl_cffi

GitHub: lexiforest/curl_cffi

一个基于 curl-impersonate 的 Python HTTP 客户端库,能够模拟主流浏览器的 TLS/JA3 和 HTTP/2 指纹,帮助绕过基于流量指纹的反爬与检测机制。

Stars: 5467 | Forks: 468

# curl_cffi [![PyPI 下载量](https://static.pepy.tech/badge/curl-cffi/week)](https://peppy.tech/projects/curl-cffi) ![PyPI - Python 版本](https://img.shields.io/pypi/pyversions/curl_cffi) [![PyPI 版本](https://badge.fury.io/py/curl-cffi.svg)](https://badge.fury.io/py/curl-cffi) [![通用徽章](https://img.shields.io/badge/Telegram%20Channel-join-blue?logo=telegram)](https://t.me/impersonate_pro) [![通用徽章](https://img.shields.io/badge/Discord-join-purple?logo=blue)](https://discord.gg/kJqMHHgdn2) [文档](https://curl-cffi.readthedocs.io) 通过 [cffi](https://cffi.readthedocs.io/en/latest/) 实现的 [curl-impersonate fork](https://github.com/lexiforest/curl-impersonate) 的 Python 绑定。如需商业支持,请访问 [impersonate.pro](https://impersonate.pro)。 `curl_cffi` 是最流行的 `curl` Python 绑定。与其他纯 Python HTTP 客户端(如 `httpx` 或 `requests`)不同,`curl_cffi` 可以模拟浏览器的 TLS/JA3 和 HTTP/2 指纹。如果你被某些网站莫名其妙地封锁,可以尝试使用 `curl_cffi`。 自 v0.14 起,Python 3.10 是最低支持版本。 ## 近期亮点 - 💨 在 `v0.15.0` 中添加了 http/3 指纹和 UDP socks5 代理支持! - 🦞 添加了 `curl-cffi` CLI 及其调试技能,可用于 claws/agents。 ## Impersonate 套件 `curl-cffi` 是 Impersonate 套件的一部分。 - [curl-impersonate](https://github.com/lexiforest/curl-impersonate)。一个可模拟浏览器的 curl 发行版。 - [curl_cffi](https://github.com/lexiforest/curl_cffi)。curl-impersonate 的 Python 绑定。 - [impers](https://github.com/lexiforest/impers)。curl-impersonate 的 Node.js 绑定。 - [impersonate.pro](https://impersonate.pro)。商业支持、更多指纹及集成解决方案。 ## 功能 - 支持 JA3/TLS 和 http2 指纹模拟,包括最新的浏览器指纹和自定义指纹。 - 比 requests/httpx 快得多,与 aiohttp/pycurl 相当,请参阅[基准测试](https://github.com/lexiforest/curl_cffi/tree/main/benchmark)。 - 模仿 requests 的 API,无需学习新接口。 - 预编译,无需在本地机器上编译。 - 支持 `asyncio` 并在每次请求时进行代理轮换。 - 支持 requests 不支持的 HTTP 2.0。 - 支持 HTTP 3.0,包含指纹和 UDP 代理。 - 支持 websocket。 - 采用 MIT 许可证。 ||requests|aiohttp|httpx|pycurl|curl_cffi| |---|---|---|---|---|---| |http/2|❌|❌|✅|✅|✅| |http/3|❌|❌|❌|☑️1|✅2| |同步|✅|❌|✅|✅|✅| |异步|❌|✅|✅|❌|✅| |websocket|❌|✅|❌|❌|✅| |原生重试|❌|❌|❌|❌|✅| |指纹|❌|❌|❌|❌|✅| |速度|🐇|🐇🐇|🐇|🐇🐇|🐇🐇| 说明: 1. 对于 pycurl,http/3 通常在编译时默认被禁用。 2. v0.11.4 起支持 http/3,v0.15.0 起支持 http/3 代理和指纹。 ### curl-cffi 命令行工具 (新) 自 v0.15 起,`curl_cffi` 附带了一个名为 `curl-cffi` 的 CLI,你可以使用 `--impersonate` 选项来调试特定的 URL。它也可以作为“claws”和“agents”的 `web_fetch` 替代品。 ||curl|httpie|curl-cffi| |---|---|---|---| |http/2|✅|❌|✅| |http/3|☑️1|❌|✅| |易用性|☑️2|✅|✅| |彩色输出|❌|✅|✅3| |指纹|❌|❌|✅| 说明: 1. 你需要启用 http/3 的 curl 构建版本,默认情况下未启用,至少在我的机器上是如此。 2. 作为一个长期的命令行用户,我个人觉得使用 `curl -X POST httpbin.org` 非常顺手,但有些用户可能更喜欢 `http GET httpbin.org` 语法。如果你更喜欢 curl 语法,可以继续使用 `curl-impersonate`。 3. 安装 `curl_cffi[cli]` 以获得彩色的 CLI 输出。在没有 `rich` 的情况下,CLI 使用纯文本输出。 ## 安装 ``` pip install curl_cffi --upgrade ``` 开箱即用,支持 Linux、macOS 和 Windows。 在 macOS 上,你也可以通过 Homebrew 安装: ``` brew install lexiforest/tap/curl-cffi ``` Android 支持(包括 Termux)目前处于测试阶段,你可以安装测试版进行体验。 对于 BSD 系统,我们需要先让 libcurl-impersonate 编译通过,然后再在 curl_cffi 中添加支持。 如果你正在使用这些操作系统,请施以援手。 要安装测试版: ``` pip install curl_cffi --upgrade --pre ``` 要安装来自 GitHub 的不稳定版本: ``` git clone https://github.com/lexiforest/curl_cffi/ cd curl_cffi make preprocess pip install . ``` ## 用法 `curl_cffi` 附带了一个底层的 `curl` API 和一个类似于 `requests` 的高级 API。 `curl_cffi` 还捆绑了一个名为 `curl-cffi` 的 CLI。 ### 命令行 ``` curl-cffi get tls.browserleaks.com/json # curl-cffi 可能难以输入,如果需要可以使用别名 alias imp=curl-cffi imp get tls.browserleaks.com/json --impersonate chrome ``` 有关完整的 CLI 指南,请参阅[文档](https://curl-cffi.readthedocs.io)。 ### 类 requests API ``` import curl_cffi # 注意 impersonate 参数 r = curl_cffi.get("https://tls.browserleaks.com/json", impersonate="chrome") print(r.json()) # 输出: {..., "ja3n_hash": "aa56c057ad164ec4fdcb7a5a283be9fc", ...} # js3n 指纹应该与目标浏览器相同 # 为了在 curl_cffi 更新时保持使用最新的浏览器版本, # 只需设置 impersonate="chrome" 而不指定版本。 # 其他类似的值包括:"safari" 和 "safari_ios" r = curl_cffi.get("https://tls.browserleaks.com/json", impersonate="chrome") # 在模拟身份时使用 http/3 r = curl_cffi.get( "https://fp.impersonate.pro/api/http3", http_version="v3", impersonate="chrome" ) # 要固定特定版本,请结合使用版本号。 r = curl_cffi.get("https://tls.browserleaks.com/json", impersonate="chrome124") # 要模拟浏览器以外的客户端,请提供你自己的 ja3/akamai 字符串 # 详情请参见 examples 目录。 r = curl_cffi.get("https://tls.browserleaks.com/json", ja3=..., akamai=...) # 支持 http/socks 代理 proxies = {"https": "http://localhost:3128"} r = curl_cffi.get("https://tls.browserleaks.com/json", impersonate="chrome", proxies=proxies) proxies = {"https": "socks://localhost:3128"} r = curl_cffi.get("https://tls.browserleaks.com/json", impersonate="chrome", proxies=proxies) ``` ### 会话 ``` s = curl_cffi.Session() # httpbin 是一个 http 测试网站,此端点会让服务器设置 cookies s.get("https://httpbin.org/cookies/set/foo/bar") print(s.cookies) # ]> # 再次获取 cookies 以进行验证 r = s.get("https://httpbin.org/cookies") print(r.json()) # {'cookies': {'foo': 'bar'}} ``` ### 支持模拟的浏览器 `curl_cffi` 支持与我 [fork](https://github.com/lexiforest/curl-impersonate) 的 [curl-impersonate](https://github.com/lwthiker/curl-impersonate) 所支持的相同浏览器版本: `curl_cffi` 的开源版本包含了与以前版本指纹不同的版本。 如果你发现某个版本(例如 `chrome135`)被跳过了,你可以直接使用自己的请求头和之前的版本来模拟它。 如果你不想自己去查找请求头等信息,可以考虑从 [impersonate.pro](https://impersonate.pro) 购买商业支持。 我们拥有针对各种平台上几乎所有浏览器版本的综合浏览器指纹数据库。 如果你尝试模拟浏览器以外的其他目标,请使用 `ja3=...` 和 `akamai=...` 来指定自定义指纹。详情请参阅[关于模拟的文档](https://curl-cffi.readthedocs.io/en/latest/impersonate/_index.html)。 要查看完整的指纹列表,请使用命令行: ``` curl-cffi list ``` 自 v0.15.1 起,你可以使用 `curl-cffi update` 来获取最新的指纹,而无需升级到新版本。 我们免费提供 Safari、Chrome、Firefox 的更新,其他的则作为[商业计划](https://impersonate.pro)的一部分提供。 下表是当前版本中内置的指纹。 |浏览器|开源版|专业版| |---|---|---| |Chrome|chrome99, chrome100, chrome101, chrome104, chrome107, chrome110, chrome116[1], chrome119[1], chrome120[1], chrome123[3], chrome124[3], chrome131[5], chrome133a[5][6], chrome136[8], chrome142[11], chrome145[13][14], chrome146[13][14]|chrome132, chrome134, chrome135| |Chrome Android| chrome99_android, chrome131_android[5]|chrome132_android, chrome133_android, chrome134_android, chrome135_android| |Chrome iOS|N/A|即将推出| |Safari[9]|safari153[2], safari155[2], safari170[1], safari180[4], safari184[8], safari260[10], safari2601[11]|即将推出| |Safari iOS[9]| safari172_ios[1], safari180_ios[4], safari184_ios[8], safari260_ios[10]|即将推出| |Firefox|firefox133[5], firefox135[7], firefox144[11][12], firefox147[13][14]|即将推出| |Firefox Android|N/A|firefox135_android| |Tor|tor145[8]|即将推出| |Edge|edge99, edge101|edge133, edge135| |Opera|N/A|即将推出| |Brave|N/A|即将推出| 说明: 1. 在 `0.6.0` 版本中添加。 2. 在 `0.6.0` 版本中修复,之前的 http2 指纹[不正确](https://github.com/lwthiker/curl-impersonate/issues/215)。 3. 在 `0.7.0` 版本中添加。 4. 在 `0.8.0` 版本中添加。 5. 在 `0.9.0` 版本中添加。 6. 版本后缀 `a`(例如 `chrome133a`)表示这是一个替代版本,即指纹尚未被浏览器正式更新,但由于 A/B 测试已被观察到。 7. 在 `0.10.0` 版本中添加。 8. 在 `0.11.0` 版本中添加。 9. 自 `0.11.0` 起,首选 `safari184_ios` 格式而不是 `safari18_4_ios`,两者都支持,但后者容易混淆且难以解析。 10. 在 `0.12.0` 版本中添加。 11. 在 `0.14.0` 版本中添加。 12. 在 `0.15.0` 版本中修复,之前的 User-Agent 请求头[不正确](https://github.com/lexiforest/curl-impersonate/issues/234)。 13. 在 `0.15.0` 版本中添加。 14. 包含 http3 支持。 ### Asyncio ``` from curl_cffi import AsyncSession async with AsyncSession() as s: r = await s.get("https://example.com") ``` 更多并发用法: ``` import asyncio from curl_cffi import AsyncSession urls = [ "https://google.com/", "https://facebook.com/", "https://twitter.com/", ] async with AsyncSession() as s: tasks = [] for url in urls: task = s.get(url) tasks.append(task) results = await asyncio.gather(*tasks) ``` 有关底层 API、Scrapy 集成和其他高级主题,请参阅[文档](https://curl-cffi.readthedocs.io)获取更多详情。 ### WebSockets ``` from curl_cffi import WebSocket def on_message(ws: WebSocket, message: str | bytes): print(message) ws = WebSocket(on_message=on_message) ws.run_forever("wss://api.gemini.com/v1/marketdata/BTCUSD") ``` ### Asyncio WebSockets ``` import asyncio from curl_cffi import AsyncSession async with AsyncSession() as session: async with session.ws_connect("wss://echo.websocket.org") as ws: await asyncio.gather(*[ws.send_str("Hello, World!") for _ in range(10)]) async for message in ws: print(message) ``` 请参阅 WebSocket [文档](https://curl-cffi.readthedocs.io/en/latest/websockets.html)获取完整的详情和高级选项。 ## 生态系统 - 与 Scrapy 集成:[divtiply/scrapy-curl-cffi](https://github.com/divtiply/scrapy-curl-cffi)、[jxlil/scrapy-impersonate](https://github.com/jxlil/scrapy-impersonate) 和 [tieyongjie/scrapy-fingerprint](https://github.com/tieyongjie/scrapy-fingerprint)。 - 作为适配器与 [requests](https://github.com/el1s7/curl-adapter)、[httpx](https://github.com/vgavro/httpx-curl-cffi) 集成。 - 与验证码解析器集成:[YesCaptcha](https://yescaptcha.com/i/stfnIO)。 ## 致谢 - 最初 fork 自 [multippt/python_curl_cffi](https://github.com/multippt/python_curl_cffi),该项目采用 MIT 许可证。 - Headers/Cookies 文件复制自 [httpx](https://github.com/encode/httpx/blob/master/httpx/_models.py),该项目采用 BSD 许可证。 - Asyncio 支持的灵感来自 Tornado 的 curl http 客户端。 - 同步 WebSocket API 的灵感来自 [websocket_client](https://github.com/websocket-client/websocket-client)。 - 异步 WebSocket API 的灵感来自 [aiohttp](https://github.com/aio-libs/aiohttp)。 ## 贡献 在提交 PR 时,请使用除 `main` 之外的分支,并勾选“Allow edits by maintainers”复选框,以便我可以用 lint 或样式修复来更新你的 PR。谢谢! ### AI 政策 - 既不鼓励也不反对使用 AI,由你自行选择。 - 这里的底线是每一行代码都应该**由人类审查**,并且应该[被证明是有效的](https://simonwillison.net/2025/Dec/18/code-proven-to-work/)。 - AI 不一定能想出最简洁的解决方案,你有责任引导它走向你所知的正确方向。 - 修复所有的 lint 错误,确保你的代码遵循本项目既定的约定。 - LLM 往往会生成过多或没有注释,请修改注释并确保它们简洁有用。 - **绝对不能**使用 LLM 生成整个 PR 摘要。要与其他人交流,请使用人类的语言。 - 唯一可接受的例外是,如果你的母语不是英语,可以使用它来修复语法问题。 - 这里的核心是保持[人类参与](https://discourse.llvm.org/t/rfc-llvm-ai-tool-policy-human-in-the-loop/89159) 你甚至可以将上述政策喂给你的“copilot”,让它为你调整风格。 :P
标签:cffi, curl-impersonate, DNS解析, HTTP/2指纹, HTTP/3指纹, JA3指纹伪造, SOCKS5代理, TLS指纹模拟, 云资产清单, 反爬虫, 开源项目, 异步编程, 指纹浏览器, 爬虫开发, 网络安全, 网络请求, 计算机取证, 逆向工具, 逆向工程, 隐私保护