How to Convert a URL to PNG with wkhtmltoimage in Python
Convert a web page URL to PNG in Python with IMGKit and wkhtmltoimage. Install both dependencies, configure rendering, and troubleshoot common failures.
Direct answer: Install the Python wrapper imgkit and the separate wkhtmltoimage executable, then call imgkit.from_url() with PNG output enabled:
import imgkit
imgkit.from_url(
"https://example.com",
"page.png",
options={"format": "png"},
)
IMGKit is only the wrapper; it launches wkhtmltoimage to render the page. If that executable is missing or inaccessible, the Python package alone cannot capture the URL. IMGKit documents URL, file, and HTML-string inputs, as well as returning image bytes when the output argument is False. See the IMGKit documentation.
1. Install Python and wkhtmltoimage
Install IMGKit into the Python environment that will run your script:
python -m pip install imgkit
Install the wkhtmltoimage executable separately. It is commonly distributed with the wkhtmltopdf package. Follow the installation instructions for your operating system and verify that the executable is available:
wkhtmltoimage --version
If the command is not found, locate the executable or add its directory to PATH. The Python wrapper must be able to launch it. IMGKit notes that some headless server environments may also need Xvfb.
2. Convert a URL to a PNG file
Save this as capture.py and run it with the same Python interpreter where IMGKit is installed:
import imgkit
url = "https://example.com"
output_path = "page.png"
imgkit.from_url(
url,
output_path,
options={"format": "png"},
)
print(f"Saved {output_path}")
Use an explicit URL scheme such as https://, set the format to png, and use a destination ending in .png. IMGKit option names omit the command-line -- prefix.
3. Configure the renderer and output
Set the executable path explicitly
If IMGKit cannot find wkhtmltoimage through PATH, configure the executable path directly:
import imgkit
config = imgkit.config(wkhtmltoimage="/usr/local/bin/wkhtmltoimage")
imgkit.from_url(
"https://example.com",
"page.png",
options={"format": "png"},
config=config,
)
Replace the path with the location on the machine running the script. On Windows, provide the full path to wkhtmltoimage.exe.
Return PNG bytes instead of writing a file
Pass False for the output argument to receive the rendered bytes. This is useful when another part of your Python program uploads or processes the image:
import imgkit
png_bytes = imgkit.from_url(
"https://example.com",
False,
options={"format": "png"},
)
with open("page.png", "wb") as image_file:
image_file.write(png_bytes)
Adjust viewport and JavaScript timing
IMGKit passes rendering options to wkhtmltoimage. For example, set a viewport width and height, or wait after page load for JavaScript-rendered content:
options = {
"format": "png",
"width": 1440,
"height": 1000,
"javascript-delay": 1500,
}
imgkit.from_url("https://example.com", "page.png", options=options)
The manual documents --width, --height, --javascript-delay, --disable-javascript, image loading controls, crop dimensions, and local-file access controls. Screen height defaults to a value calculated from page content; width guides the viewport unless smart width is disabled. Consult the wkhtmltoimage command manual for supported options in your installed build.
Use headers or cookies for authenticated pages
Options that can be repeated, such as cookies and custom headers, can be supplied as lists or tuples in IMGKit. Keep secrets out of source control and avoid printing authentication values in logs. The exact request configuration should match the target site’s authentication requirements.
Use file or HTML inputs
IMGKit also provides methods for rendering a local HTML file or an HTML string, in addition to from_url. This can help when you already have markup to render. Local file access may be restricted by wkhtmltoimage options, so enable it only when the input needs access to local resources.
4. Understand rendering limits and page timing
wkhtmltoimage uses the Qt WebKit rendering engine. It should not be assumed to render exactly like a current Chromium, Firefox, or Safari browser, especially for modern CSS or JavaScript behavior. The installed binary build matters: the wkhtmltopdf project notes the engine used, while IMGKit warns that some Debian and Ubuntu builds omit Qt patches and have reduced functionality.
A capture can vary with viewport size, JavaScript execution, load timing, remote assets, and the renderer build. For repeatable output, hold those inputs steady, choose an explicit width, allow only the delay the page needs, and verify behavior against the exact installed executable.
5. Troubleshoot common failures
| Symptom | Likely cause | What to do |
|---|---|---|
No wkhtmltoimage executable found |
The binary is not installed, is not on PATH, or the Python process has a different environment. |
Run wkhtmltoimage --version in the same environment, then add its directory to PATH or set imgkit.config(wkhtmltoimage=...). |
| Failure on a headless server | The environment may need a virtual X server. | Install Xvfb where appropriate and use IMGKit’s documented xvfb option for that setup. |
| Features behave differently on Linux | A distribution-provided binary may be built without the Qt patches and features expected by the project. | Identify the installed build and check the desired option against it; compare with a supported patched build if needed. |
| PNG is blank or content is missing | The page may rely on delayed JavaScript, remote assets, or a feature unsupported by the installed renderer. | Check the URL in the same network environment, enable JavaScript if needed, tune javascript-delay, and inspect the renderer’s supported behavior. |
| The process exits with a command error or segmentation fault | The underlying executable or its build failed; this may not be a Python exception caused by your script. | Use IMGKit’s command output to run the generated command directly and inspect wkhtmltoimage’s error. IMGKit notes that some versions may fail with segmentation faults. |
| Local images or stylesheets do not load | Local-file access controls may prevent the renderer from reading those resources. | Check the manual’s local-file access options and grant access only to the needed files. |
6. Performance, reliability, and cost considerations
Each conversion starts a rendering executable and waits on page loading and rendering, so total time depends on the page, network, assets, and any configured JavaScript delay. Keep captures bounded to the viewport and content you need, avoid excessive delays, and reuse a configured environment rather than reinstalling dependencies for each capture.
For reliability, pin and document the wkhtmltoimage build used in deployment, test representative pages in that environment, and handle command failures and timeouts in the surrounding application. A successful Python call does not guarantee that every modern page will render as it does in a full browser.
The software components described here are IMGKit and wkhtmltoimage; the cited documentation does not establish a hosted rendering charge or a benchmark. Account for the compute and maintenance costs of the machine where the executable runs, and separately verify any licensing or deployment requirements for your use.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. For example, this cURL call saves a PNG capture:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-d format=png \
-o shot.png
See the ScreenshotNeo API documentation for request parameters. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Is wkhtmltoimage a Python library?
No. wkhtmltoimage is a separate executable; IMGKit is the Python wrapper that invokes it.
Can I render without saving to disk?
Yes. Use False as the output argument to have IMGKit return the image bytes.
Does a PNG extension alone guarantee PNG output?
Set options={"format": "png"} explicitly and use a .png destination so both the requested format and filename agree.
Will the result match a modern browser pixel for pixel?
Not necessarily. The renderer uses Qt WebKit, and page features and installed build can affect the result.


