Chrome浏览器广告点击代码问题求助:仅首次点击成功后续报错
Hey there, I see exactly why your code only works for the first ad—let's break this down and fix it!
The Root Cause
Your initial code grabs all ad elements upfront and stores them in CountingAds. But when you navigate away from the search page (by clicking an ad) and then call driver.Navigate().Back(), the browser re-renders the search page. The element references in your original CountingAds list are now stale—they no longer point to valid elements in the current page's DOM. That's why every click after the first throws an error.
Solution 1: Re-locate Ads on Each Loop Iteration
Instead of storing all ads at once, re-find the ad elements every time you return to the search page. This ensures you're always interacting with fresh, valid DOM elements:
// Get the total number of ads first (initial count) int totalAds = driver.FindElements(By.XPath("//a[@onmousedown='return google.arwt(this)']")).Count; for (int i = 0; i < totalAds; i++) { System.Threading.Thread.Sleep(5000); // Re-locate the i-th ad element on the current page IWebElement currentAd = driver.FindElements(By.XPath("//a[@onmousedown='return google.arwt(this)']"))[i]; currentAd.Click(); driver.Navigate().Back(); // Optional: Wait a bit for the search page to fully reload before next iteration System.Threading.Thread.Sleep(2000); }
Solution 2: Use Explicit Waits (More Reliable Than Thread.Sleep)
Thread.Sleep is a blunt tool—it waits a fixed time even if the page loads faster. Using explicit waits ensures you only interact with elements once they're ready, making your code more stable:
using OpenQA.Selenium.Support.UI; // Set up a wait that times out after 10 seconds WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); // Wait for ads to load and get the total count int totalAds = wait.Until(d => d.FindElements(By.XPath("//a[@onmousedown='return google.arwt(this)']")).Count); for (int i = 0; i < totalAds; i++) { // Wait for the i-th ad to be clickable IWebElement currentAd = wait.Until(d => d.FindElements(By.XPath("//a[@onmousedown='return google.arwt(this)']"))[i] ); currentAd.Click(); driver.Navigate().Back(); // Wait for the search page to reload (e.g., wait for the search box to be visible) wait.Until(d => d.FindElement(By.Name("q")).Displayed); }
Key Takeaway
Never store element references across page navigations—DOM changes invalidate those references. Always re-locate elements after navigating back/forward or refreshing a page.
内容的提问来源于stack exchange,提问作者Baig

