DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk4 min

How to Get a Page’s HTML with Puppeteer

Use page.content() to retrieve a page’s current full HTML with Puppeteer, including its DOCTYPE. Learn element extraction, waiting for dynamic content, and handling missing selectors.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To get the current page’s full HTML with Puppeteer, navigate to the page and call await page.content(). It returns the page’s serialized HTML, including the DOCTYPE. For one element, use page.$eval(); for all matching elements, use page.$$eval().

Get the full page HTML

Page.content() returns a promise containing the full HTML contents of the current page, including its DOCTYPE. The current Puppeteer API reference documents this method in version 25.12.0: Puppeteer Page.content().

As an Amazon Associate I earn from qualifying purchases.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.goto('https://example.com');

  const html = await page.content();
  console.log(html);
} finally {
  await browser.close();
}

Save the result to a file if you need to inspect or process it later:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import { writeFile } from 'node:fs/promises';
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  const html = await page.content();
  await writeFile('page.html', html, 'utf8');
} finally {
  await browser.close();
}

This captures the current document representation after navigation. It is not necessarily the exact original HTTP response body: scripts may have changed the DOM, and serialization is not a byte-for-byte recovery of the network response.

Choose the right extraction method

What you need Use What it returns
Entire current document await page.content() Full HTML, including the DOCTYPE
Custom DOM value or transformation page.evaluate(() => ...) The value returned by your function in the page’s JavaScript context
One element’s markup page.$eval(selector, callback) The callback result for the first matching element
Markup for every matching element page.$$eval(selector, callback) An array of callback results

Read the document element with evaluate

page.evaluate() runs its function in the page context, making it useful for custom DOM extraction. For example, serialize the root document element:

const html = await page.evaluate(() => document.documentElement.outerHTML);

This reads the document element’s outerHTML; unlike page.content(), that expression does not itself include the document’s DOCTYPE. Puppeteer’s guide also demonstrates extracting document.body.innerHTML: JavaScript execution.

Get one element’s outerHTML

Use $eval() when you know the selector and want one matching element’s serialized markup:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const sectionHtml = await page.$eval('main', element => element.outerHTML);

$eval() throws an error if the selector matches no element. The API reference documents that behavior: Puppeteer Page.$eval().

Get markup for all matching elements

Use $$eval() to apply a function to every matching element and return the results as an array:

const cardHtml = await page.$$eval('.card', elements =>
  elements.map(element => element.outerHTML)
);

For example, cardHtml is an array of the matching cards’ markup. See the official page interactions guide for the query methods.

Wait for dynamic content before reading

page.goto() completing does not guarantee that every client-rendered component or asynchronously loaded section is ready for extraction. If you need a particular element, wait for the page to reach that state before reading it. Puppeteer recommends locators for element interactions because they wait for the element and relevant action preconditions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.goto('https://example.com');
await page.locator('main').wait();
const mainHtml = await page.$eval('main', element => element.outerHTML);

The locator wait helps when the selector appears later than the initial document. Choose a selector that represents the content you actually need; waiting for a generic element may still be too early if the page fills it in afterward.

Best Value
The SQL Programming Language: .
  • Used Book in Good Condition
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handle missing selectors safely

If an element is optional, check for it before extracting. page.$() returns a handle when it finds a match and null when it does not, so the script can avoid the exception that $eval() would raise:

const section = await page.$('main');
const sectionHtml = section
  ? await section.evaluate(element => element.outerHTML)
  : null;

if (sectionHtml === null) {
  console.log('No main element found');
}

Use this pattern when absence is a valid outcome. If the element should always exist, a clear selector failure may be more useful than silently returning null.

Current DOM versus original response HTML

Puppeteer’s page.content() and page.evaluate() expose the page’s current document representation. They are appropriate when you want the DOM after scripts have run, including client-side changes. If you need the exact original response body as received over HTTP, do not treat serialized DOM as a substitute: capture or inspect the navigation response separately. The APIs cited here describe DOM extraction, not the response-body retrieval procedure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your goal is a screenshot or PDF rather than extracting HTML, ScreenshotNeo offers a website screenshot API and MCP server. A single GET request can return an image or PDF. For example, with cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

See the ScreenshotNeo documentation for API options. It removes supported cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. Its MCP server gives AI agents screenshot tools, and the free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up free for ScreenshotNeo.

Troubleshooting

  • $eval() reports that no element matched: Check that the selector is correct and that the element exists at extraction time. For delayed content, wait for the selector; if it is optional, use page.$() and handle its null result.
  • The HTML lacks content you see later in the browser: The page may render or update that content asynchronously. Wait for the specific element or state before calling page.content() or evaluating markup.
  • The output differs from “View Source” or the original response: page.content() serializes the current page document, which may have been changed by JavaScript. It is not a byte-for-byte copy of the original HTTP response.
  • The output omits the DOCTYPE: If the DOCTYPE is required, use page.content(); serializing document.documentElement.outerHTML returns the root element’s markup.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.