Overview
Extracting data from web pages is one of the primary use cases for HtmlUnit. Because HtmlUnit models a real web browser (including DOM tree generation, CSS evaluation, and JavaScript execution), it offers powerful capabilities for extracting structured data, raw text, HTML fragments, and element attributes.
Extracting Rendered Text with asNormalizedText()
The primary method for extracting human-readable content from any DOM node or page is
asNormalizedText().
Unlike standard raw text getters, asNormalizedText() simulates how text is actually rendered on screen:
- Collapses consecutive whitespace sequences into single spaces.
- Appends line breaks (
\n) between block-level CSS elements (such as<p>,<div>, or<tr>). - Ignores invisible DOM elements like
<script>and<style>tags. - Respects CSS visibility settings, excluding content hidden via rules such as
display: noneorvisibility: hidden.
Extracting Text from a Targeted Element
For targeted extraction, combine CSS or XPath selectors with asNormalizedText():
try (final WebClient webClient = new WebClient()) {
final HtmlPage page = webClient.getPage("https://www.htmlunit.org/");
// Locate element via CSS Selector
final DomNode article = page.querySelector("article.main-content");
if (article != null) {
String text = article.asNormalizedText();
System.out.println(text);
}
}Extracting Text from the Entire Page
Calling asNormalizedText() directly on the HtmlPage or HtmlBody retrieves all visible text across the document.
final String fullPageText = page.asNormalizedText();
Extracting HTML / XML Source
If you need the underlying markup rather than plain text, HtmlUnit provides asXml() on all DOM nodes.
Serializing the DOM with asXml()
Calling asXml() serializes the current state of a node (and its child subtree) into valid XML/HTML markup.
Because it reads from the active DOM tree, it includes any dynamic changes made by JavaScript after page load.
-
Calling
page.asXml()returns the entire rendered document markup. -
Calling
element.asXml()returns the HTML/XML representation of that specific element and its descendants.
// Get full serialized XML/HTML representation of the page DOM
final String pageXml = page.asXml();
// Get the HTML/XML code of a specific element and its children
final HtmlDivision div = page.getHtmlElementById("content");
final String divXml = div.asXml();Extracting Attributes and Links
When scraping web sites, extracting element attributes (such as href, src, or data-* attributes) is common.
// Extract all links with their target URLs
final List<HtmlAnchor> anchors = page.getAnchors();
for (final HtmlAnchor anchor : anchors) {
String text = anchor.asNormalizedText();
String href = anchor.getHrefAttribute();
System.out.println(text + " -> " + href);
}
// Extract specific image sources
final DomNodeList<DomElement> images = page.getElementsByTagName("img");
for (final DomElement img : images) {
String src = img.getAttribute("src");
String alt = img.getAttribute("alt");
}Navigating Links: Prefer .click() over Extracting href
With traditional raw scrapers, navigating to a new page typically requires extracting the href attribute string and manually issuing a new GET request.
Because HtmlUnit simulates a real browser, in most cases you do not need to extract the href attribute. Instead, simply call click() directly on the anchor element:
// Find an anchor by its text or selector
final HtmlAnchor link = page.getAnchorByText("Documentation");
// Simulate a real user click - handles JavaScript onclick handlers, relative URLs, and redirects automatically
final HtmlPage targetPage = link.click();
Using click() is strongly recommended over extracting `href` manually because it:
- Triggers any attached JavaScript
onclickevent handlers. - Handles single-page application (SPA) client-side routing.
- Resolves relative paths, base tags, and redirects automatically.
- Maintains browser session state, cookies, and window history.
Structured Extraction with Tables
For tabular data, HtmlUnit provides specialized wrappers like HtmlTable, HtmlTableRow, and HtmlTableCell that simplify extracting rows and columns.
final HtmlTable table = page.getHtmlElementById("data-table");
for (final HtmlTableRow row : table.getRows()) {
for (final HtmlTableCell cell : row.getCells()) {
System.out.print(cell.asNormalizedText() + "\t");
}
System.out.println();
}For deeper table manipulation details, see the dedicated Tables guide.
Combining HtmlUnit with Jsoup
If you prefer Jsoup's fluent CSS selector and DOM manipulation API for content extraction, you can use the official
htmlunit-jsoup bridge. This allows HtmlUnit to handle JavaScript execution and browser navigation, while providing a Jsoup Document interface for extraction.
Where to Go Next
- Getting Started - Learn the basics of loading pages and interacting with forms.
- Use JavaScript - Ensure dynamic content is fully loaded before extracting text.
- Use Tables - Advanced table extraction techniques.

