What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
To convert HTML to PDF with images, use a browser renderer such as Puppeteer or Playwright when the page depends on JavaScript or needs to look like a modern browser-rendered webpage. Wait for the page and its images to load, then call page.pdf() with printBackground: true if CSS background images or colors matter. For a Python workflow that does not need browser JavaScript, WeasyPrint can render HTML and CSS directly with HTML(...).write_pdf().
Missing images usually come down to relative URLs without a base address, resources that the converter cannot reach, JavaScript that has not finished inserting images, print styles that hide them, or disabled background printing. The right fix depends on which renderer you use and how the source page loads its assets.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
PDF Explained: The ISO Standard for Document Exchange | $14.41 | Buy on Amazon |
| 2 |
|
Adobe Acrobat 6 PDF For Dummies | $13.00 | Buy on Amazon |
| 3 |
|
Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware... | $13.39 | Buy on Amazon |
Choose a renderer that matches the page
HTML-to-PDF conversion is not just saving markup as a file. The converter must resolve stylesheets, fonts, images, and other resources, then lay out the document across pages. If JavaScript builds the page or browser-specific rendering is important, use Chromium through Puppeteer or Playwright. If the input is mostly static HTML and CSS and you want a Python-based pipeline without launching a browser, use WeasyPrint.
| Renderer | Good fit | Important behavior |
|---|---|---|
| Puppeteer | Pages that require JavaScript or Chromium-style browser rendering | page.pdf() uses print CSS by default. Screen CSS can be selected before generating the PDF. |
| Playwright | Pages that require browser rendering and JavaScript | page.pdf() uses print CSS by default. Its PDF API supports paper dimensions, margins, page ranges, scale, and background printing. |
| WeasyPrint | Python workflows for HTML and CSS that do not require browser JavaScript | Accepts URLs, filenames, file objects, and HTML strings; relative resources need a usable base URL or custom URL fetcher. |
There is no quantitative speed or performance comparison established here, so choose based on rendering requirements, resource access, and deployment constraints rather than an assumed speed ranking.
#1 Best Overall
Convert a webpage with Puppeteer
Puppeteer controls a browser page, navigates to the URL, and exports the rendered page to PDF. The basic sequence is launch, navigate, generate the PDF, then close the browser. Install Puppeteer in your Node.js project using your usual package manager, and save this as an ES module, for example convert.mjs.
import puppeteer from 'puppeteer';
const url = process.argv[2];
if (!url) {
throw new Error('Usage: node convert.mjs <url>');
}
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle2' });
await page.pdf({
path: 'output.pdf',
format: 'A4',
printBackground: true
});
} finally {
await browser.close();
}
Run it with node convert.mjs https://example.com, replacing the example URL with the page to export. networkidle2 waits for navigation activity to settle, which can help when styles, fonts, or images load after the initial response. A page that continuously polls or loads resources in the background may never reach a useful idle state; in that case, use a different navigation readiness condition and wait explicitly for a meaningful selector or image state before exporting.
Puppeteer generates the PDF using the print CSS media type unless you change it. To render the screen stylesheet instead, add await page.emulateMediaType('screen'); after navigation and before page.pdf(). Use this only when the screen layout is the intended PDF design: print styles often deliberately remove navigation, adjust columns, and reflow content for paper.
Convert a webpage with Playwright
Playwright also uses a browser page and exports with page.pdf(). In the example below, page.emulateMedia({ media: 'screen' }) requests screen CSS; remove that line to use print CSS.
Recommended Free Tools
import { chromium } from 'playwright';
const url = process.argv[2];
if (!url) {
throw new Error('Usage: node convert-playwright.mjs <url>');
}
const browser = await chromium.launch();
try {
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle' });
await page.emulateMedia({ media: 'screen' });
await page.pdf({
path: 'page.pdf',
format: 'A4',
printBackground: true
});
} finally {
await browser.close();
}
Run it as node convert-playwright.mjs https://example.com. Use screen media only if the page’s screen stylesheet produces the layout you want on paper. If a page has a carefully designed @media print stylesheet, leave screen emulation out.
Convert HTML with WeasyPrint
WeasyPrint is a direct option for Python when the document can be rendered from HTML and CSS without executing page JavaScript. Install WeasyPrint for your environment, then use the relevant form below.
from weasyprint import HTML
# A local file: relative images and stylesheets resolve from the file location.
HTML(filename='input.html').write_pdf('output.pdf')
# An HTML string: pass the page's base URL so relative resources can resolve.
html_text = '<h1>Report</h1><img src="images/chart.png">'
HTML(string=html_text, base_url='https://example.com/reports/').write_pdf('report.pdf')
For string input, choose a base_url that matches the location from which relative URLs should resolve. For instance, with src="images/chart.png" and base URL https://example.com/reports/, the resource is resolved relative to that directory. WeasyPrint accepts URLs, filenames, file objects, and in-memory HTML strings. It supports PNG, JPEG, and GIF raster images as well as SVG; SVG images are rendered as vectors in the PDF.
Rank #2
Set page size, margins, colors, and page ranges
Browser PDF methods use print CSS by default, so first decide whether to honor the document’s print rules or its screen appearance. Then set PDF options for the parts that should be controlled by the export process.
- Paper dimensions: Puppeteer and Playwright support a paper format or explicit width and height. Playwright treats unlabeled dimensions as pixels; dimensions with units can use values such as
px,in,cm, ormm. - CSS page size: Use
preferCSSPageSizewhen the page’s CSS@pagerules should determine the PDF page dimensions rather than the API’s configured format or width and height. - Margins: Set margins in the PDF options, or define them in print CSS. Avoid assuming both sets of rules will combine in the way you intend; inspect a sample output.
- Backgrounds and colors: Set
printBackground: trueto include CSS background graphics. For exact print colors in Chromium, use-webkit-print-color-adjustin the page’s CSS where appropriate. A background option does not override a print stylesheet that hides an element. - Page ranges and scale: Use
pageRangesto export selected pages andscaleto adjust the rendered output. Check that scaled content remains legible and does not create unwanted whitespace or clipping.
Puppeteer’s PDF generation waits for fonts by default. That does not guarantee every image or JavaScript-inserted asset is ready, so handle those separately when images are missing.
Why images are missing from the PDF
Relative image URLs have no base
An image reference such as src="../img/logo.png" needs a document location to resolve against. In WeasyPrint, pass a filename or URL, or specify base_url when rendering an HTML string. With Puppeteer or Playwright, navigate to a real origin rather than rendering isolated markup with unresolved relative paths. An absolute image URL can also avoid ambiguity.
The converter cannot access the resource
Check that the image URL is valid from the machine running the conversion, not just from your own browser. The resource may require cookies or authentication, be blocked by network policy, redirect elsewhere, or return an error. WeasyPrint supports local files, HTTP, FTP, and data URIs, but does not provide advanced cookie and authentication handling without a custom URL fetcher. If assets are protected, determine how credentials will be provided before choosing a renderer.
The page was exported before images appeared
Navigation completion is not always the same as page readiness. A script may insert an image after the initial load or populate it only after a user interaction. Wait for the relevant DOM element or application-specific ready condition before calling page.pdf(). If the site loads content progressively, check the image’s src and rendered state rather than relying on a short fixed delay.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →CSS backgrounds were not printed
Images placed in CSS background-image are different from HTML <img> elements. Enable printBackground: true in Puppeteer or Playwright. Then inspect print styles, since CSS can still remove backgrounds or hide their containing element.
Print CSS hides or changes the image
Inspect @media print rules and computed styles for display, visibility, and opacity. A page may intentionally omit decorative images for print, or change a multi-column layout in a way that moves an image to another page. Test with screen CSS only if that is the desired design; otherwise correct the print stylesheet.
Rank #3
- Used Book in Good Condition
Reduce PDF size and manage repeated assets
WeasyPrint provides optimize_images, jpeg_quality, dpi, and cache options. Lower JPEG quality or DPI can reduce file size, but can also soften photographs or small details; inspect the resulting PDF at its intended viewing size. Caching can avoid downloading and parsing the same images repeatedly in workflows that reuse them. For PDF/A output, WeasyPrint’s documentation notes that images may need image-rendering: crisp-edges to avoid forbidden anti-aliasing.
For browser-rendered PDFs, output size and runtime depend on the page, its assets, and rendering setup. Avoid claiming one renderer is always faster or smaller: there is no dated, primary benchmark establishing a universal performance winner.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesSecurity when converting untrusted HTML
HTML conversion can cause the rendering process to retrieve remote resources, follow redirects, or load local assets. WeasyPrint warns that untrusted HTML or CSS can create security problems. Treat both the document and its referenced URLs as untrusted when building a conversion service.
- Sanitize or sandbox user-supplied HTML and CSS.
- Restrict outbound requests and control which hosts or resource types the renderer can access.
- Consider how redirects, local-file references, cookies, and authentication could expose data.
- Use a custom URL fetcher or isolated execution environment when the application requires stricter resource controls.
- Do not treat a successful PDF render as proof that every fetched resource was safe.
Or skip the browser setup
If your input is a publicly reachable webpage and you want an API rather than managing a browser, ScreenshotNeo offers a website screenshot API and MCP server. Its PDF options are documented with the API at ScreenshotNeo’s documentation. The following one-call example is the documented image response pattern, adapted to the page you want to capture:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and whether the request was billed. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Common conversion problems and fixes
| Symptom | Likely cause | What to check |
|---|---|---|
| PDF contains text but not image files | Relative paths cannot resolve, or image host is unreachable | Set a base URL or navigate to the page origin; test each resource from the converter host. |
| HTML images appear, but colored panels or hero backgrounds vanish | Background printing is disabled or print CSS removes them | Enable printBackground and inspect @media print rules. |
| Only some images are absent | Lazy loading, delayed JavaScript, authentication, or an individual broken URL | Wait for the image/application ready state and check each image request and its response. |
| Layout differs from the web page | PDF generation is using print CSS | Review print styles; use screen media only when screen layout is the intended PDF design. |
| PDF has unexpected paper dimensions or whitespace | API page settings and CSS @page rules conflict |
Choose whether API options or CSS should control size; check margins and preferCSSPageSize. |
| Protected assets fail in WeasyPrint | Cookies or advanced authentication are needed | Use a custom URL fetcher or choose a browser workflow that can load the authenticated page. |
Which method should you use?
- Choose Puppeteer or Playwright for JavaScript-heavy pages, browser layout fidelity, or pages that need normal browser authentication and interaction.
- Choose WeasyPrint for Python-centric generation from HTML and CSS when browser JavaScript is not required and resource URLs can be resolved safely.
- For either browser tool, make the CSS media type, background printing, paper dimensions, margins, and readiness conditions explicit instead of relying on defaults.
- Before scaling conversion to user-submitted content, isolate rendering and restrict network access.
Frequently Asked Questions
Does Puppeteer include web fonts in its PDF?
Puppeteer’s PDF generation waits for fonts by default, though the font still has to load successfully in the page.
Can WeasyPrint render SVG images?
Yes. WeasyPrint supports SVG, and SVG images are rendered as vectors in the PDF.
Can I print only selected pages?
Puppeteer and Playwright provide a pageRanges PDF option for selecting pages.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




