Disclaimer: I do not accept responsibility for any issues arising from scripts being run without adequate understanding. It is the user's responsibility to review and assess any code before execution. More information

Reading Specific Elements with Selenium: From HTML to Extracted Data


When I first started working with Selenium for monitoring or data extraction tasks, one of the trickiest parts was understanding how to reliably target a specific element on a page.

There’s a big difference between simply seeing something in your browser and actually being able to read it in code.

In this post, I’ll walk through the complete process of locating, identifying, and programmatically extracting content from any HTML element using Selenium. I’ll use PowerShell syntax since that’s the environment I use for most automation, but the principles apply to all Selenium languages.

Step 1. Identifying the Element in DevTools

The first step is always manual inspection.

  1. Open the web page in Microsoft Edge or Chrome.
  2. Right-click the area of the page you’re interested in and choose Inspect.
  3. DevTools will open and highlight the corresponding HTML element.

For example, let’s say I want to read a queue number from a dashboard like this:

<div class="queue-status">
  <span class="queue-title">Message Defense Timeout</span>
  <a href="/messages/timeout" class="queue-value">7</a>
</div>

From DevTools, I can see two key things:

  • The text label (Message Defense Timeout)
  • The linked number (7) I want to extract

This structure tells me there’s a <div> wrapping the section, with an <a> tag holding the numeric value.

Step 2. Content Locator Strategy

Selenium needs a locator — a precise way to find that element in the page structure.

  • By.Id() – if the element has a unique ID attribute.
  • By.ClassName() – for a class (not unique in many cases).
  • By.CssSelector() – for advanced patterns using CSS syntax.
  • By.XPath() – for path-based matching, useful for text relationships.

For example, the element above can be targeted by XPath:

$xpath = "//span[text()='Message Defense Timeout']/following::a[1]"

This reads as:

Find a <span> whose text equals “Message Defense Timeout”, then locate the first <a> element that follows it.

This is exactly how I identify related numeric values that follow a title or label.

Step 3. Translating the Locator to Selenium Code

Once I have my locator, I can implement it in Selenium.

Here’s an example in PowerShell using the Selenium WebDriver DLL:

$element = $driver.FindElement([OpenQA.Selenium.By]::XPath($xpath))
$value = $element.Text

If $element exists, $value will now hold the text "7".

I can also add a wait so that the script pauses until the element appears:

$wait = New-Object OpenQA.Selenium.Support.UI.WebDriverWait($driver, [TimeSpan]::FromSeconds(15))
$element = $wait.Until([OpenQA.Selenium.Support.UI.ExpectedConditions]::ElementExists([OpenQA.Selenium.By]::XPath($xpath)))
$value = $element.Text

Using waits is important — many modern web pages are dynamic, and trying to read before the content loads will fail.

Step 4. Handling Missing Elements Gracefully

If the element doesn’t appear or the structure changes slightly, you’ll want your script to handle it without crashing.

Example:

try {
    $element = $driver.FindElement([OpenQA.Selenium.By]::XPath($xpath))
    $value = $element.Text
    Write-Host "Found value: $value"
} catch {
    Write-Host "Element not found for: $xpath"
    $value = 0
}

This ensures that even if something changes on the page, the script continues to run and simply reports “not found.”

Step 5. Working with Complex HTML Blocks

Sometimes, the data you need is inside a more complicated structure — tables, nested divs, or sections that update dynamically with JavaScript.
In those cases, it helps to print out the inner HTML of a higher-level container and look at it in your log file:

$container = $driver.FindElement([OpenQA.Selenium.By]::CssSelector("div.queue-status"))
$html = $container.GetAttribute("innerHTML")
Write-Host $html

From this, I can see what’s really being rendered, then refine my locator to target the correct child element.

Step 6. Extracting Multiple Values

If you expect several elements with similar structure (for example, several queue entries), you can use FindElements instead of FindElement:

$elements = $driver.FindElements([OpenQA.Selenium.By]::CssSelector("a.queue-value"))
foreach ($item in $elements) {
    Write-Host "Found value: $($item.Text)"
}

This will iterate through all matches — ideal for dashboards or list pages.

Step 7. Converting Extracted Data into Usable Output

Once I have the data, I can do anything with it:

  • Write it to a log
  • Compare against a threshold
  • Send it in an email report
  • Insert it into a CSV or HTML file

For example:

if ([int]$value -gt 0) {
    Send-MailMessage -To "alerts@domain.com" -Subject "Queue Alert" -Body "Queue has $value messages pending."
}

Step 8. Testing and Maintaining Locators

Web pages change frequently, so locators can break.
My process is to:

  1. Reopen DevTools after an error.
  2. Reinspect the same section.
  3. Adjust the XPath or CSS selector.
  4. Retest with FindElement() manually.

A stable locator strategy often relies on text or class combinations that are least likely to change — avoid numeric indexes when possible.

Conclusion

Extracting specific data from a web page isn’t just about writing Selenium commands — it’s about understanding the page structure.
Once I learned to read the DOM and choose the right locator type, automating tasks like Proofpoint queue monitoring, logins, or web reporting became straightforward.

When combined with a stable runtime script and proper logging, this technique allows for fully automated, professional-grade reporting without human interaction.

Previous Post Next Post

نموذج الاتصال