Only using class names is not sufficient in your case.
By.cssSelector(".ban")
has 15 matching nodes
By.cssSelector(".hot")
has 11 matching nodes
By.cssSelector(".ban.hot")
has 5 matching nodes
Therefore you need more restrictions to narrow it down. Option 1 and 2 below are available for css selector, 1 might be the one that suits your needs best.
Option 1: Using list items' index (CssSelector or XPath)
Limitations
- Not stable enough if site's structure changes
Example:
driver.FindElement(By.CssSelector("#rightbar > .menu > li:nth-of-type(3) > h5"));
driver.FindElement(By.XPath("//*[@id='rightbar']/ul/li[3]/h5"));
Option 2: Using Selenium's FindElements
, then index them. (CssSelector or XPath)
Limitations
- Not stable enough if site's structure changes
- Not the native selector's way
Example:
// note that By.CssSelector(".ban.hot") and //*[contains(@class, 'ban hot')] are different, but doesn't matter in your case
IList<IWebElement> hotBanners = driver.FindElements(By.CssSelector(".ban.hot"));
IWebElement banUsStates = hotBanners[3];
Option 3: Using text (XPath only)
Limitations
- Not for multilanguage sites
- Only for XPath, not for Selenium's CssSelector
Example:
driver.FindElement(By.XPath("//h5[contains(@class, 'ban hot') and text() = 'us states']"));
Option 4: Index the grouped selector (XPath only)
Limitations
- Not stable enough if site's structure changes
- Only for XPath, not CssSelector
Example:
driver.FindElement(By.XPath("(//h5[contains(@class, 'ban hot')])[3]"));
Option 5: Find the hidden list items link by href, then traverse back to h5 (XPath only)
Limitations
- Only for XPath, not CssSelector
- Low performance
- Tricky XPath
Example:
driver.FindElement(By.XPath(".//li[.//ul/li/a[contains(@href, 'geo.craigslist.org/iso/us/al')]]/h5"));
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…