如何使用 Selenium 和 Python 在复杂网站中找到下拉 select 元素和 select 选项

How to locate the dropdown select element and select an option within a complex website using Selenium and Python

我有一个非常复杂的网站,我正在尝试使用 Selenium 对其进行测试。但是当我尝试获取 XPath 时,我会得到这样的例子。

//*[@id="datatable1595356931082"]/div[1]/div[2]/table/tbody/tr[3]/td[2]/div/select/option[8]

绝对 XPath:

/html/body/div[4]/div[2]/div[2]/div/div[2]/div[2]/div/div/div[1]/div[2]/table/tbody/tr[3]/td[2]/div/select/option[8]

在 Selenium 中我尝试使用像

这样的绝对路径
driver.find_element_by_xpath("/html/body/div[4]/div[2]/div[2]/div/div[2]/div[2]/div/div/div[1]/div[2]/") 

它会尝试出错,说它无法找到 XPath。数据表似乎在运行时创建了一个动态数字。 我在这里要做的是 select 一个看起来像这样的下拉菜单

<div role="columnheader" class="webix_hcell webix_ss_filter">
<select>
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
.
.
.
</select>
</div>

我也试过了

driver.find_element_by_class_name('webix_hcell webix_ss_filter')

但是那也出错了

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".webix_hcell webix_ss_filter"}

对于上面那个

selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression /html/body/div[4]/div[2]/div[2]/div/div[2]/div[2]/div/div/div[1]/div[2]/ because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '/html/body/div[4]/div[2]/div[2]/div/div[2]/div[2]/div/div/div[1]/div[2]/' is not a valid XPath expression.
  (Session info: chrome=84.0.4147.89)

这行不通,因为 *_by_class_name 仅适用于单个 class 名称:

driver.find_element_by_class_name('webix_hcell webix_ss_filter')

尝试使用 *_by_css_selector:

element = driver.find_element_by_css_selector('div.webix_hcell.webix_ss_filter select')

您需要考虑以下几点:

  • 从您的第一次尝试开始,由于 id 属性值 datatable1595356931082 的存在, 显示为动态元素,这可能会在每次访问时或定期发生变化:

    //*[@id="datatable1595356931082"]/div[1]/div[2]/table/tbody/tr[3]/td[2]/div/select/option[8]
    
  • 在您的第二次尝试中,您使用了绝对 。由于网站是动态的,元素将在每次访问时或定期重新定位:

    /html/body/div[4]/div[2]/div[2]/div/div[2]/div[2]/div/div/div[1]/div[2]/table/tbody/tr[3]/td[2]/div/select/option[8]
    
  • 在您的第三次尝试中,xpath/ 结尾,这不是您想要的。因此你面对

  • 在您的第四次尝试中,您通过 driver.find_element_by_class_name('webix_hcell webix_ss_filter') 传递了多个 classes,而 driver.find_element_by_class_name() 仅接受一个 class名称作为参数。

You can find a detailed discussion in

  • 最后是一个节点,所以需要用到Select class.

You can find a detailed discussion in How to select a drop-down menu value with Selenium using Python?


解决方案

基于 HTML 的相关文本会帮助我们构建规范的答案。但是,根据 HTML 提供的单击文本为 A 的选项,您可以使用以下任一 :

  • 使用 XPATHselect_by_visible_text():

    select = Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='webix_hcell webix_ss_filter' and @role='columnheader']//following::select[1]"))))
    select.select_by_visible_text('A')
    
  • 使用 CSS_SELECTORselect_by_value():

    select = Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "div.webix_hcell.webix_ss_filter[role='columnheader'] +select"))))
    select.select_by_value('A')
    
  • 注意:您必须添加以下导入:

    from selenium.webdriver.support.ui import Select
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC