使用 selenium python 按类名查找第 n 个元素

Find nth element by classname using selenium python

我昨天刚开始使用 selenium 来帮助抓取一些数据,但我很难全神贯注于选择器引擎。我知道 lxml、BeautifulSoup、jQuery 和 Sizzle 有类似的引擎。但我想做的是:

  1. 等待 10 秒让页面完全加载
  2. 确保存在十个或更多 span.eN 个元素(初始页面加载时加载两个,之后加载更多)
  3. 然后用beautifulsoup
  4. 开始处理数据

我正在努力解决寻找第 n 个元素或定位仅存在于第 n 个元素中的特定文本的 selenium 条件。我不断收到错误(超时、NoSuchElement 等)

    url = "http://someajaxiandomain.com/that-injects-html-after-pageload.aspx"
    wd = webdriver.Chrome()
    wd.implicitly_wait(10)
    wd.get(url)
    # what I've tried
    # .find_element_by_xpath("//span[@class='eN'][10]"))
    # .until(EC.text_to_be_present_in_element(By.CSS_SELECTOR, "css=span[class='eN']:contains('foo')"))

您需要了解 Explicit Waits 的概念和等待的预期条件。

在您的情况下,您可以编写一个 custom Expected Condition 来等待定位器找到的元素计数等于 n:

from selenium.webdriver.support import expected_conditions as EC

class wait_for_n_elements_to_be_present(object):
    def __init__(self, locator, count):
        self.locator = locator
        self.count = count

    def __call__(self, driver):
        try:
            elements = EC._find_elements(driver, self.locator)
            return len(elements) >= self.count
        except StaleElementReferenceException:
            return False

用法:

n = 10  # specify how many elements to wait for

wait = WebDriverWait(driver, 10)
wait.until(wait_for_n_elements_to_be_present((By.CSS_SELECTOR, 'span.eN'), n))

可能,您也可以使用内置的预期条件,例如 presence_of_element_locatedvisibility_of_element_located 并等待单个 span.eN 元素出现或可见,例如:

wait = WebDriverWait(driver, 10)
wait.until(presence_of_element_located((By.CSS_SELECTOR, 'span.eN')))