ScreenshotNeo

BlogHow-to

How to Take a Screenshot of a Website with Browshot in Python

Use Browshot’s Python client to capture a website, wait for completion, and save a valid PNG. See options, errors, and a one-call alternative.

By the ScreenshotNeo team4 October 20267 min read

Browshot is a hosted website screenshot service, and its Python package is a client for Browshot’s API. The shortest path is to install the client, create a BrowshotClient with your API key, call its blocking simple() method, check the response code, and write the returned PNG bytes in binary mode. Use the full API when you need explicit status polling or more control over capture options.

1. Install the Browshot Python client

Follow the installation instructions on the official Browshot Python library page, which documents the package and client methods. Keep the API key outside your source code: load it from an environment variable or a secrets manager, and do not commit it to version control.

Browshot’s documentation warns that running its examples can consume credits. Check your account balance and instance requirements before making live requests. The API documentation says private and shared instances require a positive balance; costs and access depend on your account and instance.

2. Capture a page with the simple blocking method

The library’s simple workflow waits for the screenshot to finish or fail, then returns a response containing a status code and PNG data. This example saves the image only when the response indicates success:

import os
from browshot import BrowshotClient

api_key = os.environ["BROWSHOT_API_KEY"]
client = BrowshotClient(api_key)

result = client.simple("https://example.com", {})

if result.get("code") == 200 and result.get("png"):
    with open("screenshot.png", "wb") as image_file:
        image_file.write(result["png"])
    print("Saved screenshot.png")
else:
    raise RuntimeError(f"Browshot capture did not return a PNG: {result}")

Set the environment variable before running the script. For example, in a Unix-like shell:

export BROWSHOT_API_KEY="your-secret-api-key"
python screenshot.py

Use wb when writing image bytes. Text mode can corrupt a PNG. The code also checks the response before writing, so an error response is not silently saved with a .png extension.

3. Use the full API for status handling and options

The full client workflow separates creation, status checks, and image retrieval. It is useful when you want to handle an in-progress capture explicitly or need the full API’s capture options. The documented sequence is screenshot_create(), poll screenshot_info() until the state is terminal, then retrieve the image with screenshot_thumbnail().

import os
import time
from browshot import BrowshotClient

client = BrowshotClient(os.environ["BROWSHOT_API_KEY"])

created = client.screenshot_create("https://example.com", {
    "size": "screen",
})

screenshot_id = created["id"]
status = created.get("status")

while status not in ("finished", "error"):
    time.sleep(2)
    info = client.screenshot_info(screenshot_id)
    status = info.get("status")

if status == "error":
    raise RuntimeError(f"Browshot capture failed: {info.get('error', info)}")

png_bytes = client.screenshot_thumbnail(screenshot_id)
with open("screenshot.png", "wb") as image_file:
    image_file.write(png_bytes)

print("Saved screenshot.png")

Use a bounded polling loop in a production worker so a delayed or stuck job cannot occupy a worker forever. The example illustrates the documented method sequence; verify the installed client release’s return shapes and supported Python syntax against Browshot’s current library documentation before adapting it. The research for this article did not execute the sample code.

The Python library also documents a simple_file helper that writes a screenshot to a named file and reports a path on success. Consult the library page for its exact arguments and return format if you prefer a file helper over handling PNG bytes yourself.

4. Choose capture options

The full API documentation lists options that change what is captured and when:

Option What it controls When to use it
size screen captures the viewport; page captures the full page. Choose screen for a viewport image and page when the output should include content below the fold.
screen_width, screen_height Desktop viewport dimensions. Use when the page layout must render at a particular desktop size. Confirm supported bounds in the endpoint documentation.
delay Waits after page load so JavaScript can run. Use a delay for content that appears shortly after initial load. Large delays add latency and may consume credits.
cache Reuses a recent screenshot for the same URL and instance. The documented default is 24 hours; cache=0 requests a fresh capture. Keep caching for repeat captures where freshness is not essential; request a fresh capture when the page has changed.
CSS selector and other capture options The API lists selector targeting, custom headers, scripts, and saving rendered HTML. Use these when a viewport capture is insufficient or the page needs request or rendering customization.

Option availability and numeric limits can depend on the exact Browshot endpoint and instance. Documentation mirrors showed different delay ranges, so check the current official endpoint documentation rather than relying on an old example for limits.

5. Handle response states and common errors

The simple API documentation describes HTTP 200 as a successful PNG response, HTTP 400 as an invalid request, HTTP 404 as a capture failure with an explanatory X-Error header, and HTTP 302 as an in-progress request that should be followed. The full API uses states such as in_process, finished, and error. Do not assume every response body is an image.

Symptom Likely cause What to do
HTTP 400 or an invalid-request result A required value is missing or an option is malformed or unsupported. Check the URL, API key parameter, option names, and value formats against the endpoint documentation.
HTTP 404 with X-Error The capture failed; the header provides the service’s explanation. Read X-Error, verify the target URL is reachable by the service, and retry only after addressing the reported cause.
HTTP 302 or in_process The capture has not completed yet. Follow the documented redirect behavior for the simple endpoint, or poll screenshot_info() in the full workflow until completion or error.
Full API returns error The capture failed after creation. Inspect the returned error field and correct the URL, capture options, or page access issue before retrying.
Insufficient-credit or instance error The account balance does not meet the instance requirement. Check account balance and instance access before submitting more captures. Private and shared instances require a positive balance according to the API documentation.
Saved file is not a valid PNG An error payload or empty response was written as image data, or the file was opened in text mode. Check for success and non-empty image bytes first; save with wb.
Screenshot misses content rendered after load The page needs more time for client-side rendering. Try the documented delay option, then keep it as short as the page allows to limit added latency.

6. Automate interactions before capture

For pages that require a sequence of browser actions, Browshot documents an automation steps argument. Its login guide describes actions such as typing, clicking, running JavaScript, sleeping, navigating, and taking a screenshot, with CSS selectors used to target elements. This is an advanced route for pages where a plain URL capture cannot reach the desired state. Use only the actions necessary for the page, and avoid putting account passwords or other secrets in code that may be logged or shared.

See Browshot’s login and automation guide for the documented interaction workflow.

7. Performance, reliability, and cost considerations

  • Keep waits purposeful. A longer delay can allow JavaScript content to render, but increases response time. Prefer the smallest delay that captures the needed content.
  • Use cache when freshness permits. Browshot documents a 24-hour default cache for the same URL and instance, and cache=0 for a fresh screenshot. Reuse can avoid unnecessary recaptures; bypass it when you need a current page state.
  • Poll with limits. In the full API, check status at a sensible interval and impose an overall deadline. Treat error as a terminal state and surface the error instead of polling forever.
  • Validate before storing. Save only successful image data, use binary mode, and keep error details for debugging without exposing API keys.
  • Account for credits. Browshot warns its sample calls may cost credits, and private or shared instances require a positive balance. Check the current account and instance terms before running batches; the research sources do not establish universal current prices or free allowances.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF. Its API accepts the parameter names used by other screenshot APIs, which can make switching straightforward. See the ScreenshotNeo API documentation for request options.

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed, and response headers say what happened. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.

Frequently asked questions

Does Browshot run a browser on my computer?

No. Browshot is a hosted screenshot service; the Python package sends requests to its service.

Should I use the simple or full API?

Use simple() for the concise blocking workflow. Use the full create, status, and retrieval sequence when you need explicit status handling or more API options.

Why is the PNG empty or unreadable?

Check the response status and returned image bytes before writing. A failure response is not a PNG, and image data must be written in binary mode.

How do I capture an authenticated or interactive page?

The API documents custom headers and scripts, and Browshot’s automation guide describes steps such as typing and clicking. Choose the method that fits the page’s access flow, and check the current API documentation for supported options.

Sources