动态变化HTML标签的计数方法及Selenium统计页面元素数量始终为0的问题咨询
Hey there! Let's troubleshoot why your Selenium code is returning 0 for the job card count. Dynamic content (like job listings that load asynchronously) is super common on career pages, so here are the most likely fixes to get accurate numbers:
1. Wait for Elements to Load Explicitly
The biggest culprit here is usually that WebDriver tries to find elements before they've finished loading on the page. Implicit waits can be unreliable for dynamic content, so switch to explicit waits with WebDriverWait and ExpectedConditions:
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.ExpectedConditions; import java.time.Duration; // Inside your class public int getPositionCardCount() { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15)); // Adjust timeout as needed // Wait until all matching cards are visible List<WebElement> elements = wait.until( ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//div[@class='card']")) ); return elements.size(); }
This ensures your code only counts elements once they're actually visible on the page, not just present in the DOM.
2. Verify Your XPath Selector is Correct
Double-check that your selector matches the actual elements on the page:
- If the
cardclass is used alongside other classes (e.g.,<div class="card job-listing">), your current XPath won't match. Use a more flexible selector instead:// Matches elements where 'card' is a standalone class (avoids partial matches like 'card-header') By cardsNumOfPositions = By.xpath("//div[contains(concat(' ', @class, ' '), ' card ')]"); - Test your selector directly in your browser's dev tools:
- Press F12 to open DevTools
- Go to the Console tab
- Run
$x("//div[@class='card']")— if this returns an empty array, your selector is wrong. Adjust it to match the actual element structure.
3. Check for Shadow DOM (Modern Sites)
Some modern websites use Shadow DOM to encapsulate elements, which Selenium's standard findElements can't access. If that's the case, use JavaScript to query the DOM directly:
import org.openqa.selenium.JavascriptExecutor; public int getPositionCardCount() { JavascriptExecutor js = (JavascriptExecutor) driver; // Execute JS to count matching elements Long count = (Long) js.executeScript("return document.querySelectorAll('div.card').length;"); return count.intValue(); }
4. Confirm No Hidden Contexts (Just to Be Safe)
Even though you said there are no iframes, quickly confirm you're in the main page context:
driver.switchTo().defaultContent(); // Ensures you're not in any iframe/frame
Modified Full Code Example
Here's how to integrate these fixes into your existing code:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import java.time.Duration; import java.util.List; public class JobCardCounter { private WebDriver driver; private By cardsNumOfPositions = By.xpath("//div[contains(concat(' ', @class, ' '), ' card ')]"); public JobCardCounter(WebDriver driver) { this.driver = driver; } public int getPositionCardCount() { // Ensure we're in the main context driver.switchTo().defaultContent(); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15)); // Wait for at least one card to load wait.until(ExpectedConditions.visibilityOfElementLocated(cardsNumOfPositions)); List<WebElement> elements = driver.findElements(cardsNumOfPositions); return elements.size(); } public void printCountElements() { int count = getPositionCardCount(); System.out.println("Number of job cards: " + count); } }
Start with checking your selector and adding explicit waits — those two fixes resolve 90% of dynamic content counting issues. If you still get 0, try the JavaScript method to rule out Shadow DOM.
内容的提问来源于stack exchange,提问作者Bishoy Ezzat

