Playwright wrapper обеспечивающий необходимый функционал для человеко-подобного парсинга сайтов
Project description
🧰 Human Requests
Asynchronous library for browser‑like HTTP scenarios with controlled offline rendering and two‑way state transfer.
⭐ Star us on GitHub | 📚 Read the Docs | 🐛 Report a Bug
✨ Features
- HTTP by default. Direct requests via
curl_cffiin impersonate mode + real browser headers generation. - Browser on demand. Offline render of an already received response (no repeated HTTP) and JS execution.
- Unified state. Two‑way transfer of cookies and
localStoragebetween HTTP and the browser (storage_state ⇄ session). - Async by design. Native
asynciofor predictable concurrency.
🚀 Quick Start
Installation
pip install human-requests[playwright-stealth]
playwright install
Direct request (pretend to be a browser)
import asyncio
from human_requests import Session, HttpMethod
async def main():
async with Session(headless=True, browser="camoufox") as s:
resp = await s.request(HttpMethod.GET, "https://target.example/")
print(resp.status_code, len(resp.text))
asyncio.run(main())
Render an already received response (without another request)
# resp — the result of an HTTP request
async with resp.render(wait_until="networkidle") as page:
await page.wait_for_selector("#content")
# after exiting:
# - cookies and localStorage are synced back into the session
Warm‑up: inject localStorage BEFORE page start
origin = "https://target.example"
async with Session(headless=True, browser="camoufox") as s:
# prepare storage_state in advance
s.local_storage.setdefault(origin, {})
s.local_storage[origin]["seen"] = "1"
s.local_storage[origin]["ab_variant"] = "B"
# the browser starts with the required values already in place
async with s.goto_page(f"{origin}/", wait_until="networkidle"):
pass
Accessing state
# Cookies:
print(s.cookies.storage)
# LocalStorage:
print(s.local_storage.get("https://target.example", {}))
Key Characteristics
- HTTP impersonation:
curl_cffi+ browser‑grade headers on every request. - Offline render: first response interception (fulfill) and soft reloads without recreating contexts.
- State as a first‑class citizen: cookies and
localStoragesync both ways. - Unified proxy layer: single proxy format → for
curl_cffiand Playwright. - Clean stack: no external Go binaries.
Comparison: human-requests vs hrequests
| Aspect | human-requests | hrequests |
|---|---|---|
| Execution model | asyncio (native) |
sync + threads/gevent |
| HTTP impersonation | curl_cffi impersonate + per‑request browser headers |
tls-client (Go backend) |
Offline Response render |
Yes (fulfill + soft‑reload; no repeated HTTP) | Yes (post‑render with cookies/content update) |
| Cookies ↔ HTTP/Browser | Two‑way transfer | Two‑way transfer |
localStorage ↔ HTTP/Browser |
First‑class (storage_state ⇄ session) | Via page.evaluate(...) |
| Typing | mypy‑friendly | — |
| Dependencies | No Go binaries | Go backend (tls-client) |
| Built‑in HTML parser | — | selectolax |
The focus of human-requests is a controlled anti‑bot pipeline in
asyncio: HTTP by default, a browser only where needed, with state hand‑off.
🛠️ Development
Setup
git clone https://github.com/Miskler/human-requests.git
cd human-requests
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
make build
make install-dev
Commands
# Checks
pytest # tests + coverage
make lint # ruff/flake8/isort/black (if enabled)
make type-check # mypy/pyright
# Actions
make format # formatting
make docs # build documentation
Dev: local test server
# from the test_server/ folder
make serve # foreground (Ctrl+C to stop)
make stop # stop background process
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file human_requests-0.1.5.1.tar.gz.
File metadata
- Download URL: human_requests-0.1.5.1.tar.gz
- Upload date:
- Size: 34.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34a7ddb668ae915cbc47ab5a2f9cd9770082a958eeb934105818412cb288a259
|
|
| MD5 |
32de682a23537034ad9a6a35856d8cb4
|
|
| BLAKE2b-256 |
9dc0de3117370873c88e39afed6ead1f6f3aacdca0006cd9c5976dae5663d2eb
|
Provenance
The following attestation bundles were made for human_requests-0.1.5.1.tar.gz:
Publisher:
release.yml on Miskler/human-requests
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
human_requests-0.1.5.1.tar.gz -
Subject digest:
34a7ddb668ae915cbc47ab5a2f9cd9770082a958eeb934105818412cb288a259 - Sigstore transparency entry: 724713492
- Sigstore integration time:
-
Permalink:
Miskler/human-requests@48e8b5d3c36d42a57d62db728b128123b3c99ce2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Miskler
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@48e8b5d3c36d42a57d62db728b128123b3c99ce2 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file human_requests-0.1.5.1-py3-none-any.whl.
File metadata
- Download URL: human_requests-0.1.5.1-py3-none-any.whl
- Upload date:
- Size: 31.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb6beaeaa2fecebe6b25e5595367e8034f388a966088db5975ce65f7be9a0d75
|
|
| MD5 |
9bf7dab8883912e6d2d9b226b012513a
|
|
| BLAKE2b-256 |
38e97a40acfcbead01af2406a1ace0aa7607577270557e6bda1a069853fe75e8
|
Provenance
The following attestation bundles were made for human_requests-0.1.5.1-py3-none-any.whl:
Publisher:
release.yml on Miskler/human-requests
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
human_requests-0.1.5.1-py3-none-any.whl -
Subject digest:
bb6beaeaa2fecebe6b25e5595367e8034f388a966088db5975ce65f7be9a0d75 - Sigstore transparency entry: 724713508
- Sigstore integration time:
-
Permalink:
Miskler/human-requests@48e8b5d3c36d42a57d62db728b128123b3c99ce2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Miskler
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@48e8b5d3c36d42a57d62db728b128123b3c99ce2 -
Trigger Event:
workflow_dispatch
-
Statement type: