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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use Selenium’s script-execution API to inspect the element’s immediate childNodes, keep only nodes whose nodeType is Node.TEXT_NODE, and join those values. Selenium’s normal .text or Java getText() includes visible text from nested elements, so it cannot provide direct-text-only output.

The direct-text solution

Locate the element as usual, pass that WebElement into browser-side JavaScript, and filter its immediate child nodes. The essential expression is:

Array.from(arguments[0].childNodes)
  .filter(n => n.nodeType === Node.TEXT_NODE)
  .map(n => n.nodeValue.trim())
  .filter(Boolean)
  .join(' ')

This reads text nodes that belong directly to the target element. Text inside a nested <span>, link, emphasis tag, or any other descendant element is excluded. The example above returns a normalized string: each direct node is trimmed, empty nodes are removed, and the remaining pieces are separated by one space.

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

Why Selenium .text includes nested text

Selenium’s ordinary text accessors are rendered-text accessors, not direct-child accessors. The JavaScript WebElement API describes getText() as returning visible text “including sub-elements,” and the Selenium Java API uses the same semantics. Selenium’s element-information documentation calls this rendered text. Therefore, an element such as:

#1 Best Overall
Amazon Basics Wired QWERTY Keyboard, Works with Windows, Plug and Play, Easy to Use with Media Control, Full-Sized, Black
  • KEYBOARD: The keyboard works for Windows with hot keys that enable easy access to Media, My Computer, Mute, Volume up/down, and Calculator
  • EASY SETUP: Experience simple installation with the USB wired connection
  • VERSATILE COMPATIBILITY: This keyboard is designed to work with multiple Windows versions, including Vista, 7, 8, 10 offering broad compatibility across devices.
  • SLEEK DESIGN: The elegant black color of the wired keyboard complements your tech and decor, adding a stylish and cohesive look to any setup without sacrificing function.
  • FULL-SIZED CONVENIENCE: The standard QWERTY layout of this keyboard set offers a familiar typing experience, ideal for both professional tasks and personal use.
<div class="example">
  Alpha <span>nested</span> Omega
</div>

can produce Alpha nested Omega through .text or getText(). That behavior is useful when you want what a user sees, but it is wrong when the nested value must be ignored.

The DOM gives you the distinction Selenium’s text accessor does not. childNodes contains every immediate child node, including text nodes and element nodes. children contains only child elements, so using it would lose the text you need. Filtering for Node.TEXT_NODE keeps direct text while skipping nested elements and everything below them.

Python: complete implementation

In Python Selenium, call execute_script with the located element as an argument:

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.
from selenium import webdriver
from selenium.webdriver.common.by import By


driver = webdriver.Chrome()
try:
    driver.get("https://example.com")

    el = driver.find_element(By.CSS_SELECTOR, "div.example")
    direct_text = driver.execute_script(
        "return Array.from(arguments[0].childNodes)"
        ".filter(n => n.nodeType === Node.TEXT_NODE)"
        ".map(n => n.nodeValue.trim())"
        ".filter(Boolean)"
        ".join(' ')",
        el,
    )

    print(direct_text)
finally:
    driver.quit()

execute_script serializes the returned JavaScript string back to Python. Passing el as an argument is preferable to interpolating a selector into JavaScript: Selenium transfers the actual element reference, and the script operates on exactly the element you located.

A reusable Python helper

def direct_text(driver, element, *, normalize=True):
    if normalize:
        return driver.execute_script(
            "return Array.from(arguments[0].childNodes)"
            ".filter(n => n.nodeType === Node.TEXT_NODE)"
            ".map(n => n.nodeValue.trim())"
            ".filter(Boolean)"
            ".join(' ')",
            element,
        )

    return driver.execute_script(
        "return Array.from(arguments[0].childNodes)"
        ".filter(n => n.nodeType === Node.TEXT_NODE)"
        ".map(n => n.nodeValue)",
        element,
    )

The normalized branch returns one string. The raw branch returns an array of the original direct-node values, which is safer when whitespace itself carries meaning. You can concatenate that array yourself under rules appropriate to the page.

Java: complete implementation

Java uses JavascriptExecutor and casts the returned value to String:

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class DirectText {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        try {
            driver.get("https://example.com");

            WebElement el = driver.findElement(By.cssSelector("div.example"));
            String directText = (String) ((JavascriptExecutor) driver).executeScript(
                "return Array.from(arguments[0].childNodes)"
                    + ".filter(n => n.nodeType === Node.TEXT_NODE)"
                    + ".map(n => n.nodeValue.trim())"
                    + ".filter(Boolean)"
                    + ".join(' ')",
                el
            );

            System.out.println(directText);
        } finally {
            driver.quit();
        }
    }
}

The Java API documentation for Selenium 4.28.0 also notes an important XPath detail: .// scopes a search to descendants of the current element, while // starts from the document. That distinction matters when locating the parent before extracting its direct text.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
Logitech MK270 Full Size Wireless Keyboard and Mouse Combo - Black
  • Reliable Plug and Play: The USB receiver provides a reliable wireless connection up to 33 ft (1), so you can forget about drop-outs and delays and you can take it wherever you use your computer
  • Type in Comfort: The design of this keyboard creates a comfortable typing experience thanks to the low-profile, quiet keys and standard layout with full-size F-keys, number pad, and arrow keys
  • Durable and Resilient: This full-size wireless keyboard features a spill-resistant design (2), durable keys and sturdy tilt legs with adjustable height
  • Long Battery Life: MK270 combo features a 36-month keyboard and 12-month mouse battery life (3), along with on/off switches allowing you to go months without the hassle of changing batteries
  • Easy to Use: This wireless keyboard and mouse combo features 8 multimedia hotkeys for instant access to the Internet, email, play/pause, and volume so you can easily check out your favorite sites

Other Selenium language bindings

Bindings that expose JavaScript execution use the same browser-side expression. Find the element with that binding’s normal locator method, pass the element as a script argument, and read the returned string. Confirm the exact method signature for the Selenium version used by your project; the DOM algorithm itself does not change.

Whitespace: choose your output policy

HTML source frequently places indentation and line breaks between tags. Those characters can be represented by text nodes. A direct-node filter therefore needs an explicit whitespace policy.

Normalized human-readable text

Use trim(), discard empty values, and join with one space when the result is a label, title, or assertion where formatting is irrelevant. The Python and Java examples use this policy.

Exact source spacing

If spaces, line breaks, or punctuation are significant, do not trim. Return each matching node’s nodeValue and preserve or concatenate the values according to the source markup. Trimming and joining changes the original spacing, even though it usually produces a more convenient test value.

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

Several direct pieces around a nested element

For <div>Alpha <span>nested</span> Omega</div>, the direct nodes are Alpha and Omega. The span’s nested value is not a direct node. A normalized policy yields Alpha Omega; an exact policy retains the spaces present in the two source nodes.

DOM and visibility semantics

.text applies Selenium’s visible/rendered-text behavior, including text from descendants. The JavaScript method reads DOM text nodes instead. It should not be described as a visibility filter: a text node may exist in the DOM even when CSS prevents it from being rendered. If your test requires visible-only direct text, first establish the visibility condition separately, then apply the direct-node extraction to the element that meets that condition.

Likewise, textContent is not a shortcut. Reading element.textContent aggregates text from descendants, which is exactly what this technique is meant to avoid.

Rank #3
Sale
Logitech K120 Full Size Wired Keyboard USB Plug-and-Play Windows - Black
  • All-day Comfort: The design of this standard keyboard creates a comfortable typing experience thanks to the deep-profile keys and full-size standard layout with F-keys and number pad
  • Easy to Set-up and Use: Set-up couldn't be easier, you simply plug in this corded keyboard via USB on your desktop or laptop and start using right away without any software installation
  • Compatibility: This full-size keyboard is compatible with Windows 7, 8, 10 or later, plus it's a reliable and durable partner for your desk at home, or at work
  • Spill-proof: This durable keyboard features a spill-resistant design (1), anti-fade keys and sturdy tilt legs with adjustable height, meaning this keyboard is built to last
  • Plastic parts in K120 include 51% certified post-consumer recycled plastic*

Dynamic pages and collection timing

childNodes is a live NodeList. Page scripts can insert, remove, or replace nodes while you work with it. Array.from(arguments[0].childNodes) takes a snapshot before filtering, so the operation works on one immediate-node list rather than a collection that can change during iteration.

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

You still need to locate the element at the right time. If the page renders the container asynchronously, wait for the element with your normal Selenium wait strategy before calling the script. If a framework replaces that element after you locate it, Selenium can report a stale-element failure; locate the current element again and then extract its direct nodes.

Common mistakes and fixes

Using .text or getText()

Symptom: nested labels, links, or badges appear in the result.

Cause: Selenium’s accessor intentionally includes visible descendant text.

Fix: execute the childNodes filter shown above.

Using children

Symptom: the result is empty even though the element contains visible words.

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

Cause: children returns element nodes only and omits text nodes.

Fix: use childNodes and test nodeType === Node.TEXT_NODE.

Rank #4
Redragon K521 Upgrade Rainbow LED Gaming Keyboard, 104 Keys Wired Mechanical Feeling Keyboard with Multimedia Keys, One-Touch Backlit, Anti-Ghosting, Compatible with PC, Mac, PS4/5, Xbox
  • 【Dreamy Rainbow Gaming Keyboard】K521 Gaming Keyboard Adopts a Different LED Backlight Design, Upgraded on the Traditional LED Backlight Effect, Making the Light More Penetrating, Giving You a More Dazzling Visual Effect, Making Your Gaming Process More Enjoyable
  • 【One Touch Opens & Visual Feast】The K521 Red Dragon Keyboard has a One-Touch on/off Lighting Button for Added Convenience. It also has a Three-Position Adjustable Breathing Mode and a Four-Position Adjustable Brightness Lighting Mode
  • 【Mechanical Feeling & Fast Tapping】The PC Keyboard Keys are Designed for Mechanical Feeling, Giving You a Better Feel During Use and the Ability to Trigger Keys Quickly, Allowing You to Win All Your Games
  • 【19 Keys Anti-Ghosting Keyboard】Anti-Ghosting Ensures Every Button Can Be Triggered. This Allows You to Trigger Key Combinations In The Game Accurately, And Each Skill Can Be Accurately Released to Increase Your Winning Rate. Redragon K521 Will Be Your Perfect Partner
  • 【12 Multimedia Combination Keys】The K521 Wired Gaming Keyboard is Equipped with 12 Multimedia Keys That Can Greatly Enhance Your Gaming/Office Efficiency and Make It More Convenient to Use

Using textContent on the parent

Symptom: descendant text is still present.

Cause: textContent aggregates the entire subtree.

Fix: inspect only the parent’s immediate child-node snapshot.

Unexpected blank strings

Symptom: the raw result contains empty or whitespace-only entries.

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

Cause: indentation and line breaks between tags are text nodes.

Fix: trim and filter empty values for normalized output, or deliberately preserve them when exact source formatting matters.

A stale-element exception

Symptom: script execution fails after a page update.

Cause: the framework replaced the DOM node represented by your WebElement.

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

Fix: wait for the page’s update to settle, find the element again, and pass the new reference to the script.

Best Value
Sale
Logitech K270 Full Size Wireless Keyboard for Windows - Black
  • All-day Comfort: This USB keyboard creates a comfortable and familiar typing experience thanks to the deep-profile keys and standard full-size layout with all F-keys, number pad and arrow keys
  • Built to Last: The spill-proof (2) design and durable print characters keep you on track for years to come despite any on-the-job mishaps; it’s a reliable partner for your desk at home, or at work
  • Long-lasting Battery Life: A 24-month battery life (4) means you can go for 2 years without the hassle of changing batteries of your wireless full-size keyboard
  • Simply plug the USB receiver into a USB port on your desktop, laptop or netbook computer and start using the keyboard right away without any software installation
  • Simply Wireless: Forget about drop-outs and delays thanks to a strong, reliable wireless connection with up to 33 ft range (5); K270 is compatible with Windows 7, 8, 10 or later

An XPath locator finds the wrong scope

Symptom: extraction runs against an element outside the intended container.

Cause: XPath beginning with // starts from the document, whereas .// searches below the current element.

Fix: use the relative form when searching from a previously located WebElement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Assertions and test design

Decide whether your assertion is about source structure or what a user sees. Use Selenium’s rendered-text accessor for a user-visible label that legitimately includes descendants. Use the direct-node script when the contract specifically says that only text written immediately in the container counts.

Keep the extraction policy stable across tests. A helper that always normalizes whitespace prevents one test from silently comparing raw indentation while another compares a collapsed string. Conversely, expose a raw mode when exact spacing is part of the requirement instead of hiding that decision inside a generic helper.

For diagnostic failures, log both the normalized direct value and (when safe) the list of raw direct-node values. That makes it clear whether a failure came from an unexpected nested element, whitespace-only nodes, or a genuinely changed direct label.

Performance and reliability considerations

The script examines only the target element’s immediate children; it does not recursively walk the subtree. That keeps the DOM work proportional to the number of direct nodes rather than all descendants. The dominant cost in a normal test is usually browser communication and page state, not the short filter itself.

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

Run the script after the element is present and stable, and avoid repeatedly extracting the same value inside a tight loop when one read can be reused. If the page mutates continuously, take a fresh element reference at the point of extraction and use the Array.from snapshot so one call has a consistent immediate-node view.

Or skip the browser setup

If you need a rendered screenshot or PDF of a page for a test artifact rather than direct DOM text, ScreenshotNeo provides a single HTTP request and an MCP server for AI clients. Its API can accept consent banners before capture and remove more than 60 known consent platforms, newsletter popups, and chat widgets; failed loads, bot checks or CAPTCHAs, blank pages, timeouts, and cache hits are not billed. Every response identifies the page verdict and billing status in headers.

See the ScreenshotNeo API documentation for options such as full-page capture, CSS-selector element capture, custom JavaScript, waits, blocking rules, device presets, PDFs, signed links, asynchronous jobs, and bulk capture.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Create a free ScreenshotNeo account.

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

Quick Recap

Bestseller No. 1
SaleBestseller No. 3
Logitech K120 Full Size Wired Keyboard USB Plug-and-Play Windows - Black
Logitech K120 Full Size Wired Keyboard USB Plug-and-Play Windows - Black
Plastic parts in K120 include 51% certified post-consumer recycled plastic*; Product carbon footprint: 4.02 kg CO2e
$12.34
SaleBestseller No. 5
Logitech K270 Full Size Wireless Keyboard for Windows - Black
Logitech K270 Full Size Wireless Keyboard for Windows - Black
Plastic parts in K270 include 38% certified post-consumer recycled plastic; Eight hot keys: For instant access to the Internet, e-mail, music volume and more
$21.48

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.