s-browserkit — браузерный слой китов
Живой браузер, антибот и стелс — одним китом, который ставится отдельно.
Чистой API-интеграции (белый REST/GraphQL) он не нужен и больше не навязывается:
librarykit без browserkit полностью работоспособен.
clikit adapterkit ветки-оболочки
\ /
\ /
librarykit ОРКЕСТРАТОР (сессии, лимиты, фабрики)
/ \
browserkit … СЛОЙ-КИТ (браузер и антибот)
\ /
corekit ОСНОВАНИЕ (значения и чистые правила)
Главное: просят ВОЗМОЖНОСТЬ, а не движок
import browserkit
backend = browserkit.open_browser(
browserkit.Capability.STEALTH_SESSION, # ЦЕЛЬ, а не «camoufox»
profile_dir=profile,
)
http = browserkit.make_requester(browserkit.Capability.STEALTH_REQUEST)
Соответствие «цель → движок» живёт ровно в одной таблице внутри кита
(browserkit/capabilities.py). Anti-detect движок начал палиться — правится одна
строка, ни один навык не меняется, потому что ни один навык движок не назвал.
Возможности:
| Capability | Что нужно потребителю |
|---|---|
STEALTH_SESSION |
поднять браузер там, где обычный палится antibot'ом |
VISIBLE_LOGIN |
видимое окно: пароль/2FA человек вводит руками |
PERSISTENT_WORK |
обычная автоматизация в персистентном профиле |
STEALTH_REQUEST |
один HTTP-запрос с браузерным TLS-отпечатком, БЕЗ браузера |
IN_PAGE_REQUEST |
запрос изнутри живой страницы (её cookies/TLS/заголовки) |
TRAFFIC_CAPTURE |
нормализованный сетевой трафик страницы (реверс скрытого API) |
Диагностика — «чем закрыта каждая цель прямо сейчас»:
Сразу после pip install s-browserkit (без единого extra) все цели пусты — это и
есть нормальный ответ, а не поломка:
>>> import browserkit
>>> browserkit.describe_capabilities()
{'stealth_session': None, 'visible_login': None, 'persistent_work': None,
'stealth_request': None, 'in_page_request': None, 'traffic_capture': None}
None означает «не установлен ни один исполнитель». Попытка воспользоваться такой
целью даёт внятную ошибку с рецептом установки, а не голый ModuleNotFoundError:
>>> browserkit.make_requester(browserkit.Capability.STEALTH_REQUEST)
Traceback (most recent call last):
...
browserkit.CapabilityUnavailable: Возможность 'stealth_request' недоступна:
ни один исполнитель не установлен. Поставь один из: `pip install 's-browserkit[antibot]'`.
После pip install 's-browserkit[antibot]' та же строка вернёт готовый
исполнитель (CurlCffiTransport), а describe_capabilities()['stealth_request']
станет 'tls_impersonate' — имя ИСПОЛНИТЕЛЯ цели, не пакета. Какие исполнители
стоят в очереди за каждой целью, видно заранее:
>>> browserkit.capability_plan(browserkit.Capability.STEALTH_SESSION)
('camoufox', 'nodriver', 'cdp')
Побеждает первый установленный; порядок переопределяется set_capability_plan().
Состав
browserkit.browser— лаунчеры (системный Chromium по CDP, персистентный контекст), anti-detect / undetected бэкенды,capture_tap(нормализованный event-tap над любым движком),state(storage-state, тёплый вход, детекторы протухания),egress(выход сессии и пробы «чем нас видят снаружи»),persona(часы, язык, экран и UA сессии — одним заявлением на все движки), геометрия окна, брони портов;browserkit.antibot— исполнители HTTP-запроса, ходящие «как браузер», минтер токенов тёплой страницей иtoken_cache— кэш чеканных токенов: срок жизни и одноразовость учитываются ПОРОЗНЬ, а одновременные чеканки схлопываются в одну (вместо N подъёмов браузера);browserkit.profile_health— предстартовая проверка профиля и карантин;browserkit.proc— запуск подпроцессов без всплывающих консолей;browserkit.ports— Protocol'ы, которых киту не хватает снаружи;browserkit.browser_guard+browserkit.testing— запрет браузера в рабочем пути (см. ниже).
Персона: чем сессия выглядит
Детектор 2026 года ищет не «плохой отпечаток», а ПРОТИВОРЕЧИЕ МЕЖДУ СЛОЯМИ.
Самое дешёвое для него — часы против адреса: страну называет прокси, а часовой
пояс отдаёт сам браузер. Поэтому персона (corekit.persona.ClientPersona) едет
в запуск ОДНИМ заявлением и доезжает до всех четырёх путей:
backend = browserkit.browser.build_capture_backend(
"nodriver", profile_dir=profile, proxy="socks5://fi.example:1080",
persona=persona, # часы, язык, экран, окно, UA — одним значением
)
Три правила, которые из этого следуют:
- несогласованная персона не стартует. Часы Москвы при финском выходе — это
PersonaInconsistentв конструкторе бэкенда, ДО спавна процесса. Мы отказываем, а не чиним: «починить» значит решить за вызывающего, какой из слоёв врёт; - умолчание названо. Персону не передали — кит строит её из того, что знает о
машине, и печатает перед стартом (
[browserkit.persona] …). Часы уезжают явнымtimezone_idдаже когда совпадают с системными: явное можно сверить с адресом, унаследованное молча — нельзя; - заявление проверяется наблюдением.
confirm_persona_egress(backend, plan)спрашивает у живой сессии её настоящую страну и бьётSessionEgressMismatch, если она разошлась с заявленной.
Запрет браузера в рабочем пути
Канон транспорта: браузер поднимается только чтобы сминтить сессию, работа идёт прямыми запросами. Кит делает это конструкцией — перехватом на собственных дверях запуска. Подключение к прогону навыка — одна строка:
# tests/conftest.py навыка
from browserkit.testing import forbid_real_browser # noqa: F401
Страж живёт здесь, а не в оркестраторе, ровно потому, что двери — здесь: страж и
двери едут в одном дистрибутиве, поэтому «импорт прошёл» = «двери на месте». Он
обязан честно сказать, если стеречь не может: пропажа СВОЕЙ двери валит
установку (BrowserGuardBlind), а «пакета нет» отделено от «пакет есть, двери
нет» (guard.absent / guard.blind / guard.describe()).
Подробности, боевая установка и границы применимости — docs/BROWSER_GUARD.md.
Установка
pip install s-browserkit # без движков: фасад, антибот-контракты, здоровье профиля
pip install 's-browserkit[browser]' # + Playwright (CDP-attach, персистентный контекст)
pip install 's-browserkit[camoufox]' # + anti-detect Firefox (затем `camoufox fetch`)
pip install 's-browserkit[nodriver]' # + undetected Chromium
pip install 's-browserkit[antibot]' # + TLS/JA3-импersonate без браузера
import browserkit не поднимает браузер и не импортирует ни одного движка:
подпакеты резолвятся лениво (PEP 562), вендоры — ещё позже, внутри бэкендов.
Совместимость
Прежние пути (librarykit.browser.*, librarykit.antibot.*,
librarykit.profile_health, librarykit.browser_guard, librarykit.testing)
продолжают работать: там оставлены алиасы на те же модули (sys.modules), а
не копии. Поэтому monkeypatch, isinstance и is-сравнения ведут себя ровно
как до переноса, а второй реализации стража, которая через месяц разъедется с
первой, не существует.
Тесты
uv run --no-sync pytest -q # либо .venv\Scripts\python.exe -m pytest -q
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 s_browserkit-0.0.8.tar.gz.
File metadata
- Download URL: s_browserkit-0.0.8.tar.gz
- Upload date:
- Size: 303.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
931bb8f5044912821f0e510a8babcb288cded783a75905d86e5b54835723e182
|
|
| MD5 |
38800b70dacdc250beb8c285cf170435
|
|
| BLAKE2b-256 |
8c63f6f2cb9efcff4b311d6a9d4cd384f8d84c4f83dc341cb638d7b28c65847b
|
File details
Details for the file s_browserkit-0.0.8-py3-none-any.whl.
File metadata
- Download URL: s_browserkit-0.0.8-py3-none-any.whl
- Upload date:
- Size: 172.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b3e282abf2d35fe84dd999c5b8d58b3c18b84820648ee76a2467f3d607bcd29
|
|
| MD5 |
46fb29e773109199d2f0dfdc810e6bfd
|
|
| BLAKE2b-256 |
ea2b807de908280eb314d0f87af4659b97690f8734c4291fe58c522acd9cd774
|