如何使用Selenium和Python定位下拉选择元素并在复杂网站中选择选项

2024-09-28 22:14:43 发布

您现在位置: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。datatable似乎在运行时创建了一个动态数字。 这里我要做的是选择一个下拉列表,如下所示

<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)

Tags: todivvaluehtmlseleniumbodyelementfilter
2条回答
有两件事需要考虑如下:

  • 从第一次尝试开始,WebElement将显示为动态元素,这是由于存在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/结尾,这是不需要的。因此你面对InvalidSelectorException

  • 在第四次尝试中,您通过driver.find_element_by_class_name('webix_hcell webix_ss_filter')传递了多个类,其中asdriver.find_element_by_class_name()只接受一个类名作为参数

You can find a detailed discussion in Invalid selector: Compound class names not permitted error using Selenium

  • 最后,它是一个^{}节点,因此需要使用Select

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


解决方案

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

  • 使用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
    

这不起作用,因为*_by_class_name仅用于单个类名:

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')

相关问题 更多 >