Initial version of stealthii
An aiohttp/httpx-shaped async HTTP client backed by a single, persistent, stealth-patched Chromium instance via Playwright. get/post/put/patch/ delete/head/download use context.request (real Chrome TLS/HTTP2 fingerprint, no tab needed); render()/screenshot()/page() escalate to full JS-executing page rendering for targets that need a JS challenge solved. Supports named sessions for cookie persistence/warm-up, and `async with stealth as page` to claim a tab directly, task-safe for concurrent use on one shared instance. Context/browser recycling bounds cookie and on-disk cache growth in a long-lived process. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116i7dYLNZTXNR7Lqf439bV
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
import asyncio
|
||||
|
||||
from stealthii import Stealthii
|
||||
|
||||
|
||||
async def main():
|
||||
s = Stealthii()
|
||||
|
||||
print('=== get (json) ===')
|
||||
resp = await s.get('https://httpbin.org/get', params={'a': '1'})
|
||||
print(resp.status, (await resp.json()).get('args'))
|
||||
|
||||
print('=== post (json body) ===')
|
||||
resp = await s.post('https://httpbin.org/post', json={'hello': 'world'})
|
||||
data = await resp.json()
|
||||
print(resp.status, data.get('json'))
|
||||
|
||||
print('=== post (form data) ===')
|
||||
resp = await s.post('https://httpbin.org/post', data={'x': '1', 'y': '2'})
|
||||
data = await resp.json()
|
||||
print(resp.status, data.get('form'))
|
||||
|
||||
print('=== cookies per-call ===')
|
||||
resp = await s.get('https://httpbin.org/cookies', cookies={'flavor': 'choc'})
|
||||
print(resp.status, await resp.json())
|
||||
|
||||
print('=== auth ===')
|
||||
resp = await s.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
|
||||
print(resp.status, await resp.json())
|
||||
|
||||
print('=== download (binary) ===')
|
||||
png = await s.download('https://httpbin.org/image/png')
|
||||
print('bytes:', len(png), png[:8])
|
||||
|
||||
print('=== render ===')
|
||||
r = await s.render('https://example.com', collect_links=True)
|
||||
print(r['status'], r['text'][:60], len(r['links']))
|
||||
|
||||
print('=== screenshot (base64) ===')
|
||||
b64 = await s.screenshot('https://example.com')
|
||||
print('b64 len:', len(b64))
|
||||
|
||||
print('=== screenshot (path) ===')
|
||||
path = await s.screenshot('https://example.com', path='/tmp/stealthii_shot.png')
|
||||
print('saved to', path)
|
||||
|
||||
print('=== session warm-up (cookie persistence) ===')
|
||||
await s.get('https://httpbin.org/cookies/set/persisted/yes', session='warm', allow_redirects=True)
|
||||
resp = await s.get('https://httpbin.org/cookies', session='warm')
|
||||
print(await resp.json())
|
||||
|
||||
print('=== fingerprint_info (ja4 default) ===')
|
||||
print(await s.fingerprint_info())
|
||||
|
||||
await s.shutdown()
|
||||
print('OK - all smoke checks completed')
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user