---
description: Reading a HTML Web Table There are times when we need to access elements (usually texts) that are within HTML tables. However, it is very seldom for a web designer to provide an id or name attribute t
title: How to Handle Web Table in Selenium
image: https://www.guru99.com/images/how-to-handle-web-table-in-selenium.png
---

 

[Skip to content](#main) 

**⚡ Smart Summary**

Selenium Web Table handling lets QA engineers read tabular data from HTML rows and columns using XPath, CSS, and Selenium 4 relative locators. This article walks through static tables, nested tables, attribute predicates, and AI techniques for dynamic grids.

* 🧱 **XPath Anatomy:** Every table locator starts with //table and drills into tbody, tr, and td using predicates.
* 🔁 **Dynamic Rows:** findElements returns a List of WebElements so loops can count rows and read cells at runtime.
* 🪄 **Selenium 4:** Relative locators above, below, and near simplify targeting cells around a known anchor element.
* 🧠 **AI Locators:** Self-healing tools detect column shifts and recover row identity without manual XPath edits.
* 🛠️ **Inspect Shortcut:** Browser DevTools copy a full XPath that you can trim back to the first table for reliability.

[ Read More ](javascript:void%280%29;) 

![Selenium Web Table XPath example](https://www.guru99.com/images/how-to-handle-web-table-in-selenium.png)

## What is a Web Table in Selenium?

A **Web Table** in Selenium is a WebElement used for the tabular representation of data or information. The data displayed can be either static or dynamic. Web table cells and rows are accessed through WebElement methods combined with locators. A typical example is the product specifications grid shown on an eCommerce product page.

## Reading an HTML Web Table

There are many times when testers need to access elements, usually text values, located inside HTML tables. However, web designers seldom provide an id or name attribute on individual cells. Therefore, methods such as By.id(), By.name(), or By.cssSelector() rarely work. In this scenario, the most reliable option is By.xpath() because it walks the parent-child relationships inside the table tag.

## How to Handle Web Table in Selenium

Consider the HTML code below for handling web tables in Selenium.

![How to write XPath for Table in Selenium](https://www.guru99.com/images/image019(1%29.png)

We will use [XPath](https://www.guru99.com/xpath-selenium.html) to get the inner text of the cell containing the text “fourth cell.”

![How to write XPath for Table in Selenium](https://www.guru99.com/images/image020(1%29.png)

### Step 1 – Set the Parent Element (table)

**XPath locators in WebDriver always start with a double forward slash “//” followed by the parent element**. Since we are dealing with web tables in Selenium, the parent element should always be the <table> tag. The first portion of our Selenium XPath table locator must therefore start with “//table”.

![Selenium Web Table Example](https://www.guru99.com/images/image021(1%29.png)

### Step 2 – Add the child elements

The element directly under <table> is <tbody>, so <tbody> is the child of <table>. Conversely, <table> is the parent of <tbody>. All child elements in XPath are placed to the right of their parent element, separated by one forward slash “/” as shown below.

![Selenium Web Table Example](https://www.guru99.com/images/image022(1%29.png) ![](https://www.guru99.com/images/image023.png)

### Step 3 – Add Predicates

The <tbody> element contains two <tr> tags. These two <tr> tags are children of <tbody>, so <tbody> is the parent of both. The two <tr> elements are siblings. **Siblings are child elements that share the same parent**.

To reach the <td> that contains “fourth cell”, we must first access the **second** <tr>, not the first. Writing only “//table/tbody/tr” would target the first <tr> tag.

So how do we access the second <tr>? The answer is to use **Predicates**. **Predicates are numbers or HTML attributes enclosed in square brackets “\[ \]” that distinguish a child element from its siblings**. Since the row we need is the second one, we use “\[2\]” as the predicate.

![ Selenium Web Table Example](https://www.guru99.com/images/image024.png)

If we omit the predicate, XPath returns the first sibling. Therefore, either of the XPath codes below will reach the first <tr>.

![Selenium Web Table using Xpath](https://www.guru99.com/images/image025.png)

### Step 4 – Add the Succeeding Child Elements Using the Appropriate Predicates

The next element we need is the second <td>. Applying the rules from Steps 2 and 3, we arrive at the XPath shown below.

![Web Table in Selenium using Xpath](https://www.guru99.com/images/image026.png)

Now that we have the correct XPath locator, we can access the cell and read its inner text using the code below. This assumes you have saved the HTML page as “newhtml.html” inside your C drive.

![Web Table in Selenium using Xpath](https://www.guru99.com/images/image027.png)

```
public static void main(String[] args) {
    String baseUrl = "https://demo.guru99.com/test/write-xpath-table.html";
    WebDriver driver = new FirefoxDriver();

    driver.get(baseUrl);
    String innerText = driver.findElement(
        By.xpath("//table/tbody/tr[2]/td[2]")).getText();
    System.out.println(innerText);
    driver.quit();
}
```

![Web Table in Selenium using Xpath](https://www.guru99.com/images/image028.png)

## Accessing Nested Tables

The same principles apply to nested tables. **Nested tables are tables placed inside another table**. An example is shown below.

![How to Access Nested Tables in Selenium](https://www.guru99.com/images/image029.png)![](https://www.guru99.com/images/image030.png)

To access the cell with the text “4-5-6” using the parent/child and predicate ideas from the previous section, we can compose the XPath shown below.

![How to Access Nested Tables in Selenium](https://www.guru99.com/images/image031.png)

The WebDriver code below retrieves the inner text of the targeted cell.

![Accessing Nested Tables in Selenium](https://www.guru99.com/images/SeleniumNestedTable.png)

```
public static void main(String[] args) {
    String baseUrl = "https://demo.guru99.com/test/accessing-nested-table.html";
    WebDriver driver = new FirefoxDriver();

    driver.get(baseUrl);
    String innerText = driver.findElement(
        By.xpath("//table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]")).getText();
    System.out.println(innerText);
    driver.quit();
}
```

The output below confirms that the inner table was successfully accessed.

![Accessing Nested Tables in Selenium](https://www.guru99.com/images/SeleniumNestedTableResult.png)

## Using Attributes as Predicates

If the element sits deep inside the HTML, where counting siblings becomes painful, we can use that element’s unique attribute instead.

In the example below, the “New York to Chicago” cell is buried far inside the Mercury Tours homepage.

![Selenium Web table example using Attributes as Predicates](https://www.guru99.com/images/image034.png)

![Selenium Web table example using Attributes as Predicates](https://www.guru99.com/images/burried_deep.png)

We can use the table’s unique attribute (width=”270″) as the predicate. **Attributes are used as predicates by prefixing them with the @ symbol**. In the example above, the “New York to Chicago” cell is located in the first <td> of the fourth <tr>, so our XPath should look like the one shown below.

![Selenium Web table example with Attributes as Predicates](https://www.guru99.com/images/image036.png)

Remember that when you put the XPath inside Java, escape the double quotes around “270” with a backslash so the By.xpath() string is not terminated early.

![Selenium Web table example with Attributes as Predicates](https://www.guru99.com/images/image037.png)

We are now ready to access that cell using the code below.

![Selenium Web table example with Attributes as Predicates](https://www.guru99.com/images/image038.png)

```
public static void main(String[] args) {
    String baseUrl = "https://demo.guru99.com/test/newtours/";
    WebDriver driver = new FirefoxDriver();

    driver.get(baseUrl);
    String innerText = driver.findElement(By
        .xpath("//table[@width=\"270\"]/tbody/tr[4]/td"))
        .getText();
    System.out.println(innerText);
    driver.quit();
}
```

![Selenium Web table example with Attributes as Predicates](https://www.guru99.com/images/image039.png)

## Shortcut: Use Inspect Element for Accessing Tables in Selenium

If the index or attribute of an element is hard to obtain, the fastest way to generate the XPath is by using Inspect Element in modern browser DevTools.

Consider the example below from the Mercury Tours homepage.

![Selenium Web table example with Attributes as Predicates](https://www.guru99.com/images/image040.png)

**Step 1**

Right-click the target cell and pick Inspect to view the DOM path, then copy the full XPath.

![Selenium Web table example with Attributes as Predicates](https://www.guru99.com/images/image041.png)

**Step 2**

Look for the first “table” parent element and delete everything to the left of it.

![Selenium Web table example with Attributes as Predicates](https://www.guru99.com/images/image042.png)

**Step 3**

Prefix the remaining XPath with double forward slash “//” and copy it into your WebDriver code.

![Selenium Web table example with Attributes](https://www.guru99.com/images/image043.png)

The WebDriver code below retrieves the inner text of the deeply nested element.

![Selenium Web table example with Attributes](https://www.guru99.com/images/image044.png)

```
public static void main(String[] args) {
    String baseUrl = "https://demo.guru99.com/test/newtours/";
    WebDriver driver = new FirefoxDriver();

    driver.get(baseUrl);
    String innerText = driver.findElement(By
        .xpath("//table/tbody/tr/td[2]"
        + "//table/tbody/tr[4]/td/"
        + "table/tbody/tr/td[2]/"
        + "table/tbody/tr[2]/td[1]/"
        + "table[2]/tbody/tr[3]/td[2]/font"))
        .getText();
    System.out.println(innerText);
    driver.quit();
}
```

## How to Count Rows and Columns in a Dynamic Web Table

Dynamic web tables, such as dashboards or search results, render different numbers of rows on every load. To handle them, use `findElements` to fetch every <tr> into a List, then loop through to read each cell. The snippet below counts rows and reads every cell in a table whose id is “customers”.

```
List<WebElement> rows = driver.findElements(
    By.xpath("//table[@id='customers']//tr"));
System.out.println("Total rows: " + rows.size());

for (int i = 1; i <= rows.size(); i++) {
    List<WebElement> cells = driver.findElements(
        By.xpath("//table[@id='customers']//tr[" + i + "]/td"));
    for (WebElement cell : cells) {
        System.out.println(cell.getText());
    }
}
```

Wrap the locator in a `WebDriverWait` with `visibilityOfAllElementsLocatedBy` when the table is loaded by AJAX. This prevents stale element references on slow-rendering grids.

## Selenium 4 Relative Locators for Web Tables

Selenium 4 introduced relative locators that target elements by visual position. They are useful when XPath indexes break because rows are reordered. The methods `above()`, `below()`, `toLeftOf()`, `toRightOf()`, and `near()` all accept an anchor WebElement.

```
import static org.openqa.selenium.support.locators.RelativeLocator.with;

WebElement emailHeader = driver.findElement(By.xpath("//th[text()='Email']"));
WebElement emailCell = driver.findElement(
    with(By.tagName("td")).below(emailHeader));
System.out.println(emailCell.getText());
```

Relative locators stay readable when the column order shifts. Pair them with explicit waits for the strongest results on data-driven pages.

## AI Tools for Handling Dynamic Web Tables

AI-assisted testing platforms reduce locator maintenance on grids that change often. Tools like [Testim](https://www.testim.io/), [Mabl](https://www.mabl.com/), and [Functionize](https://www.functionize.com/) use computer vision plus DOM models to detect column shifts and self-heal locators. They identify rows by header text and cell similarity rather than fixed XPath indexes.

For pure Selenium projects, libraries such as [Healenium](https://www.healenium.io/) wrap the WebDriver and rewrite broken locators at runtime. Combine these tools with WebDriverWait to keep dynamic table scripts stable without rewriting selectors after every UI change.

#### Summary

* By.xpath() is the most reliable way to access cells of a Web Table in Selenium.
* If counting siblings is hard, use a unique attribute as a predicate, prefixed with the @ symbol.
* findElements returns a List<WebElement> that supports row counting in dynamic tables.
* Selenium 4 relative locators (above, below, near) reduce dependency on positional XPath.
* Inspect Element in DevTools accelerates XPath generation for deeply buried cells.
* AI tools such as Testim, Mabl, and Healenium self-heal locators for changing grids.

## FAQs

📊 What is a Web Table in Selenium?

A Web Table in Selenium is a WebElement that displays tabular data in rows and columns. It can be static or dynamic. Testers access its cells through WebElement methods combined with XPath or CSS locators because tables rarely expose unique IDs on individual cells.

🧭 Why use XPath instead of ID or name for web tables?

Most table cells do not carry an id or name attribute, so By.id() and By.name() will not work. XPath traverses the parent-child structure of table, tbody, tr, and td elements, which makes it the most reliable locator for cells.

🔢 How do I count rows and columns in a Selenium table?

Use driver.findElements(By.xpath(“//table\[@id=’tbl’\]//tr”)).size() to count rows and //table\[@id=’tbl’\]//tr\[1\]/td for column count. The findElements method returns a List<WebElement> that supports size() for quick row totals.

🪄 What are Selenium 4 relative locators for tables?

Selenium 4 introduced relative locators like above(), below(), toLeftOf(), toRightOf(), and near(). They help target cells positioned around a known anchor cell, which is useful when XPath indexes change in dynamic tables.

🔁 How do I handle dynamic web tables in Selenium?

Loop through rows with findElements, then read each cell with getText(). Build XPath dynamically using string concatenation such as //tr\[“+i+”\]/td\[“+j+”\]. Wait for the table to load with WebDriverWait before reading values.

🤖 Can AI parse dynamic web tables automatically?

Yes. AI-powered tools like Testim, Mabl, and Functionize use computer vision and DOM models to detect table boundaries, infer headers, and self-heal locators when columns shift. This reduces XPath maintenance for dynamic dashboards.

🧠 How does AI help identify rows in flaky tables?

AI models learn row patterns from previous runs and match cells using text similarity rather than fixed indexes. When a row moves or a column gets reordered, the AI locator still finds the target without rewriting XPath.

📦 What is the difference between findElement and findElements?

findElement returns a single WebElement and throws NoSuchElementException if missing. findElements returns a List<WebElement> and returns an empty list if no match is found. Use findElements when looping over table rows or columns.

#### Summarize this post with:

ChatGPT Perplexity Grok Google AI 

**Stay Updated on AI** **Get Weekly AI Skills, Trends, Actionable Advice.** 

##### Sign up for the newsletter

Subscribe for Free 

You have successfully subscribed.  
Please check your inbox. 

![AI-Newsletter](https://www.guru99.com/images/footer-email-avatar-imges-1.png) Chosen by over **350,000+** professionals 

[Scroll to top ](#wrapper)Scroll to top 

× 

Toggle Menu Close 

Search for: 

Search

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.guru99.com/#organization","name":"Guru99","sameAs":["https://www.facebook.com/Guru99Official","https://twitter.com/guru99com"],"logo":{"@type":"ImageObject","@id":"https://www.guru99.com/#logo","url":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","contentUrl":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","caption":"Guru99","inLanguage":"en-US"}},{"@type":"WebSite","@id":"https://www.guru99.com/#website","url":"https://www.guru99.com","name":"Guru99","publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https://www.guru99.com/images/how-to-handle-web-table-in-selenium.png","url":"https://www.guru99.com/images/how-to-handle-web-table-in-selenium.png","width":"700","height":"250","caption":"How to Handle Web Table in Selenium","inLanguage":"en-US"},{"@type":"BreadcrumbList","@id":"https://www.guru99.com/selenium-webtable.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":"1","item":{"@id":"https://www.guru99.com","name":"Home"}},{"@type":"ListItem","position":"2","item":{"@id":"https://www.guru99.com/selenium","name":"Selenium"}},{"@type":"ListItem","position":"3","item":{"@id":"https://www.guru99.com/selenium-webtable.html","name":"How to Handle Web Table in Selenium"}}]},{"@type":"WebPage","@id":"https://www.guru99.com/selenium-webtable.html#webpage","url":"https://www.guru99.com/selenium-webtable.html","name":"How to Handle Web Table in Selenium","dateModified":"2026-06-17T15:44:07+05:30","isPartOf":{"@id":"https://www.guru99.com/#website"},"primaryImageOfPage":{"@id":"https://www.guru99.com/images/how-to-handle-web-table-in-selenium.png"},"inLanguage":"en-US","breadcrumb":{"@id":"https://www.guru99.com/selenium-webtable.html#breadcrumb"}},{"@type":"Person","@id":"https://www.guru99.com/author/admin","name":"Krishna Rungta","url":"https://www.guru99.com/author/admin","image":{"@type":"ImageObject","@id":"https://www.guru99.com/images/krishna-rungta-v2-120x120.png","url":"https://www.guru99.com/images/krishna-rungta-v2-120x120.png","caption":"Krishna Rungta","inLanguage":"en-US"},"worksFor":{"@id":"https://www.guru99.com/#organization"}},{"articleSection":"Selenium","headline":"How to Handle Web Table in Selenium","description":"Reading a HTML Web Table There are times when we need to access elements (usually texts) that are within HTML tables. However, it is very seldom for a web designer to provide an id or name attribute t","keywords":"selenium","speakable":{"@type":"SpeakableSpecification","cssSelector":[".entry-title",".summary"]},"@type":"Article","author":{"@id":"https://www.guru99.com/author/admin","name":"Krishna Rungta"},"dateModified":"2026-06-17T15:44:07+05:30","image":{"@id":"https://www.guru99.com/images/how-to-handle-web-table-in-selenium.png"},"copyrightYear":"2026","name":"How to Handle Web Table in Selenium","subjectOf":[{"@type":"HowTo","name":"How to Handle Web Table in Selenium","description":"Here is step by step process of How to Handle Web Table in Selenium","step":[{"@type":"HowToStep","name":"Step 1) Set the Parent Element (table)","text":"XPath locators in WebDriver always start with a double forward slash '//' and then followed by the parent element.","image":{"@type":"ImageObject","url":"https://cdn.guru99.com/images/image021(1).png"},"url":"https://www.guru99.com/selenium-webtable.html#step1"},{"@type":"HowToStep","name":"Step 2) Add the child elements","text":"The element immediately under is so we can say that is the 'child' of .","image":{"@type":"ImageObject","url":"https://cdn.guru99.com/images/image022(1).png"},"url":"https://www.guru99.com/selenium-webtable.html#step2"},{"@type":"HowToStep","name":"Step 3) Add Predicates","text":"The element contains two tags. We can now say that these two tags are 'children' of .","image":{"@type":"ImageObject","url":"https://cdn.guru99.com/images/image024.png"},"url":"https://www.guru99.com/testng-report.html#step3"},{"@type":"HowToStep","name":"Step 4) Add the Succeeding Child Elements Using the Appropriate Predicates","text":"The next element we need to access is the second . Applying the principles we have learned from steps 2 and 3, we will finalize our XPath code to be like the one shown below.","image":{"@type":"ImageObject","url":"https://cdn.guru99.com/images/image026.png"},"url":"https://www.guru99.com/selenium-webtable.html#step4"}]},{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"What is a Web Table in Selenium?","acceptedAnswer":{"@type":"Answer","text":"A Web Table in Selenium is a WebElement that displays data in rows and columns. It can be static or dynamic. Testers usually access table cells using WebElement methods with XPath or CSS locators because individual cells often do not have unique IDs."}},{"@type":"Question","name":"Why use XPath instead of ID or name for web tables?","acceptedAnswer":{"@type":"Answer","text":"Most table cells do not have id or name attributes, so By.id() and By.name() may not work. XPath can traverse the table structure through table, tbody, tr, and td elements, making it useful for locating rows, columns, and specific cells."}},{"@type":"Question","name":"How do I count rows and columns in a Selenium table?","acceptedAnswer":{"@type":"Answer","text":"Use driver.findElements(By.xpath(\"//table[@id='tbl']//tr\")).size() to count rows. For columns, use an XPath such as //table[@id='tbl']//tr[1]/td. The findElements method returns a List, and size() gives the total count."}},{"@type":"Question","name":"What are Selenium 4 relative locators for tables?","acceptedAnswer":{"@type":"Answer","text":"Selenium 4 relative locators include above(), below(), toLeftOf(), toRightOf(), and near(). They help locate elements based on their position around a known element, which can be useful when table indexes change in dynamic layouts."}},{"@type":"Question","name":"How do I handle dynamic web tables in Selenium?","acceptedAnswer":{"@type":"Answer","text":"To handle dynamic web tables, loop through rows with findElements and read cell values using getText(). You can build XPath dynamically with row and column indexes, then use WebDriverWait to make sure the table is loaded before reading data."}},{"@type":"Question","name":"Can AI parse dynamic web tables automatically?","acceptedAnswer":{"@type":"Answer","text":"Yes, AI-powered testing tools can help detect table boundaries, infer headers, and adjust locators when columns or rows shift. This can reduce XPath maintenance for dynamic dashboards, but testers should still validate important checks manually."}},{"@type":"Question","name":"How does AI help identify rows in flaky tables?","acceptedAnswer":{"@type":"Answer","text":"AI can help identify rows by using text similarity, DOM patterns, and previous test behavior instead of relying only on fixed indexes. When a row moves or a column changes position, AI-assisted locators may still find the target cell."}},{"@type":"Question","name":"What is the difference between findElement and findElements?","acceptedAnswer":{"@type":"Answer","text":"findElement returns a single WebElement and throws NoSuchElementException if no match is found. findElements returns a List and gives an empty list when there is no match, making it better for looping through table rows or columns."}}]}],"@id":"https://www.guru99.com/selenium-webtable.html#schema-23659","isPartOf":{"@id":"https://www.guru99.com/selenium-webtable.html#webpage"},"publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US","mainEntityOfPage":{"@id":"https://www.guru99.com/selenium-webtable.html#webpage"}}]}
```
