Metadata-Version: 2.4
Name: janus-requests
Version: 0.2.3
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Rust
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Dist: requests>=2.32,<3
Requires-Dist: urllib3>=2
Requires-Dist: cryptography>=42 ; extra == 'capture'
Provides-Extra: capture
License-File: LICENSE
License-File: licenses/OpenSSL-LICENSE.txt
License-File: licenses/brotli-LICENSE.txt
License-File: licenses/rust-crates.txt
License-File: licenses/zlib-LICENSE.txt
License-File: licenses/zstd-LICENSE.txt
Summary: HTTP client with an exactly specified TLS ClientHello and HTTP/2 fingerprint
Keywords: requests,tls,ja3,ja4,http2,fingerprint,impersonate
Author: Mignon Rex
License-Expression: MIT AND Apache-2.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# janus-requests

requests 兼容的 HTTP 客户端，TLS ClientHello 和 HTTP/2 帧逐字节可控：扩展顺序、GREASE、ALPS、密码套件、SETTINGS、WINDOW_UPDATE、伪头顺序、HPACK 编码都由 profile 决定。核心是 Rust，TLS 用打过补丁的 OpenSSL 4.0.3（静态链接在 wheel 里）。

```bash
uv add janus-requests
```

## 用法

```python
from janus_requests import JanusSession

with JanusSession(janus="chrome155", headers={"User-Agent": "..."}, proxy="http://127.0.0.1:7890", retry_num=2) as s:
    r = s.get("https://example.com/")
    print(r.status_code, r.raw.version_string)
```

- 不带任何默认请求头，发出去的头只有你给的（外加 Host / Content-Length / Cookie）
- `verify` 默认关，不读环境变量和系统代理
- `janus=` 接受内置名 `chrome155` 或 `JanusProfile`
- `logs=func(req, resp)` 每个响应回调一次，`retry_num=` 只重试连接类错误
- `timeout=` 可以设在 session 上（秒数或 `(connect, read)`），请求级 `timeout=` 优先
- 请求级 `headers=` 覆盖 session 的同名头，值为 `None` 表示这次不发
- `JanusAsyncSession` 是 asyncio 版本；`import janus_requests as requests` 可当 requests 用

## 从真浏览器抓 profile

```bash
uv add "janus-requests[capture]"
uv run janus-capture --name my_chrome
# 浏览器打开 https://localhost:8443/
```

打开页面当场写出 `my_chrome.py` 和 `my_chrome.json`，`import my_chrome; my_chrome.session()` 即可复现这个浏览器。页面脚本随后再开几轮新连接（`--rounds`，默认 4），补上扩展乱序和会话恢复（PSK）。抓取时关掉系统代理，否则抓到的是代理的指纹。

## 许可证

MIT。wheel 里静态链接的 OpenSSL（含 Janus 的 ClientHello 补丁）按 Apache-2.0 发布，zlib、brotli、zstd 和 Rust 依赖的许可证见 wheel 的 `.dist-info/licenses/`。

