Client

WebSkrapClient owns the Playwright lifecycle.

Use it as an async context manager:

import asyncio
 
from webskrap import WebSkrapClient
 
 
async def main() -> None:
    async with WebSkrapClient() as client:
        result = await client.fetch("https://example.com")
    print(result.status)
 
 
asyncio.run(main())

You can also manage the lifecycle manually when embedding WebSkrap in a larger async application:

client = WebSkrapClient()
await client.start()
try:
    result = await client.fetch("https://example.com")
finally:
    await client.close()

One-shot fetch

client.fetch() creates a temporary browser session, opens the page, collects the response data, then closes that temporary session.

result = await client.fetch(
    "https://example.com",
    wait_until="domcontentloaded",
    screenshot="example.png",
)

Use client.session() when you want to keep browser state or keep a headed browser open.

Wait states

wait_until is passed to Playwright navigation and supports:

ValueUse when
commitYou only need the navigation to begin.
domcontentloadedYou need parsed HTML and want a fast default.
loadYou need regular page assets to finish loading.
networkidleYou need a quiet network, usually for JS-heavy pages.

For pages with long-polling or analytics requests, networkidle can be slower or less reliable than domcontentloaded plus an explicit page wait in a session.

Screenshots and output

The Python API returns page HTML in result.text by default. Pass text_only=True when you want readable body text instead:

from pathlib import Path
 
result = await client.fetch("https://example.com", screenshot="example.png")
Path("example.html").write_text(result.text, encoding="utf-8")
print(result.screenshot_path)
 
text_result = await client.fetch("https://example.com", text_only=True)
print(text_result.text)

Pass screenshot=True to let WebSkrap choose a timestamped file name in the current working directory.

Per-call config

Pass a SessionConfig for one request without changing the client's defaults:

from webskrap import ResourcePolicy, SessionConfig
 
config = SessionConfig(
    headless=True,
    resource_policy=ResourcePolicy.LITE,
    navigation_timeout_ms=60_000,
)
result = await client.fetch("https://example.com", config=config)

FetchResult

FetchResult includes:

FieldMeaning
urlURL requested by the caller.
final_urlPage URL after redirects and navigation.
statusMain response HTTP status, or None when no response is available.
okTrue when status is 2xx or 3xx.
headersMain response headers.
textFinal page HTML from page.content().
titleFinal document title.
cookiesBrowser-context cookies visible after the fetch.
timingsTiming data, currently including elapsed_ms.
screenshot_pathScreenshot path when screenshot capture was requested.

Check status before assuming headers or HTTP semantics exist:

if result.status is None:
    print("Navigation did not return a main response")
elif result.ok:
    print("Loaded", result.final_url)
else:
    print("HTTP error", result.status)