How to extract dropdown menu options from a webpage when HtmlUnitDriver shows different HTML structure than regular browsers?

I’m trying to scrape category options from a product analysis website but getting different results with different browser drivers.

Working with regular browsers: When I use Firefox or Chrome drivers, I can easily grab the category list using this approach:

System.setProperty("webdriver.chrome.driver", "C:/drivers/chromedriver.exe");
WebDriver browser = new ChromeDriver();
browser.get("https://example-product-site.com/estimator");
List<WebElement> categoryList = new WebDriverWait(browser, 15).until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("div.category-item_text")));
for (WebElement item : categoryList)
    System.out.println(item.getText());
browser.close();

This prints the expected results:

Electronics
Home & Garden
Sports Equipment
...

Problem with HtmlUnit: However, when I switch to HtmlUnitDriver for headless browsing, the page structure appears completely different. Instead of finding the categories in span elements, I see them embedded in JavaScript data like this:

const CATEGORIES = {
    US: [
      ["Electronics", "icon-electronics"],
      ["Home & Garden", "icon-home"],
      ["Sports Equipment", "icon-sports"],
      ["Books & Media", "icon-books"],
      ["Fashion & Accessories", "icon-fashion"]
    ],
    UK: [
      ["Electronics", "icon-electronics"]
    ]
};

The categories seem to be dynamically loaded through JavaScript that creates the DOM elements. How can I extract this data when using HtmlUnit since it renders the page differently than standard browsers?

honestly htmlunit is kinda outdated for this stuff. ive had better luck just using chrome headless with --headless=new flag - it processes js exactly like regular chrome but without the gui overhead. your scraping code stays the same too.

You’re running into a classic issue where HtmlUnit’s JavaScript support doesn’t match modern browser behavior. I had similar problems with dynamically generated content and found that configuring HtmlUnit properly makes a significant difference. Try setting up HtmlUnitDriver with explicit JavaScript support and increased timeout values. The key is using setJavaScriptEnabled(true) and adjusting the script timeout since HtmlUnit processes JavaScript more slowly than real browsers. Another approach that worked for me was using HtmlUnit’s getPageSource() method after the page loads, then using Pattern matching to extract the CATEGORIES data structure directly from the HTML source. Since you can see the JavaScript object in the source, you can parse it as a string and extract the array values without relying on DOM rendering. If the site heavily relies on modern JavaScript features, consider sticking with headless Chrome using --headless flag instead of switching to HtmlUnit completely.

HtmlUnit’s JavaScript engine behaves quite differently from real browsers, which explains why you’re seeing the raw JavaScript instead of the rendered DOM elements. The issue is likely that HtmlUnit isn’t executing the JavaScript that transforms that CATEGORIES object into actual DOM elements.

I’ve encountered this exact scenario before and found two approaches that work well. First, you can enable JavaScript execution in HtmlUnit by setting the browser capabilities properly, but even then it might not fully replicate how Chrome handles dynamic content loading.

The more reliable solution I’ve used is to extract the JavaScript data directly using JavaScriptExecutor or by parsing the page source for that CATEGORIES object. You can use a simple regex or JSON parser to extract the array data from the JavaScript block. Something like finding the text between “CATEGORIES = {” and the closing brace, then parsing just the array portion you need.

This approach actually gives you cleaner data since you’re getting it directly from the source rather than waiting for DOM manipulation to complete.