需求
使用selenium点击下拉框,选中【是】选项。
代码
方法1
# 点击下拉框
driver.find_element('xpath','//*[@id="basicProcessDetail"]/div[2]/div[2]/div[1]/div/div[2]/div/div/div/div[1]/div[2]/form/div[11]/div[1]/div/div/div[1]/div[1]/div/i').click()
# 点击对应的选项
driver.find_element('xpath','//*[@id="basicProcessDetail"]/div[2]/div[2]/div[1]/div/div[2]/div/div/div/div[1]/div[2]/form/div[11]/div[1]/div/div/div[1]/div[2]/ul[2]/li[1]').click()
缺点:无法批量操作,每次都得复制很长的xpath表达式,费时费力。
方法2
def select_option(label_text, option_text):
"""点选操作"""
print(f'点选【{label_text}】', end='-> ')
try:
# 等待元素加载完成
wait = WebDriverWait(driver, 10) # 增加等待时间到10秒
# 使用XPath定位包含特定文本的元素,然后找到其后的下拉框按钮
dropdown_button = wait.until(EC.element_to_be_clickable((By.XPATH,
f"//label[contains(text(), '{label_text}')]/following-sibling::div//div[contains(@class, 'ivu-select-selection')]")))
# 点击下拉框按钮
dropdown_button.click()
# 使用XPath定位并点击特定的选项
option_button = wait.until(EC.element_to_be_clickable((By.XPATH,
f"//label[contains(text(), '{label_text}')]/following-sibling::div//div[contains(@class, 'ivu-select-dropdown')]//li[contains(text(), '{option_text}')]")))
option_button.click()
print('成功!')
except Exception as e:
print('失败!')
# 调用
select_option("是否保护:", "是")
优点:可封装函数,方便批量操作类似的下拉框。
讲解
分析:
关于第二个XPath表达式的理解和分析:
功能:用于定位包含特定文本的<li>
元素,它包含了两个主要部分:
- 定位包含特定文本的
<label>
元素://label[contains(text(), '{label_text}')]
:这部分XPath用于定位所有<label>
元素,这些元素的文本包含您提供的label_text
变量。{label_text}
是一个占位符,代表您想要定位的标签文本,例如“是否双板卡保护:”。
- 定位
<label>
元素的后续兄弟节点中的<div>
元素:/following-sibling::div
:这表示我们想要找到<label>
元素的后续兄弟节点,即紧随其后的<div>
元素。
- 定位
<div>
元素中的<div>
元素,该<div>
包含ivu-select-dropdown
类://div[contains(@class, 'ivu-select-dropdown')]
:这表示我们想要找到包含ivu-select-dropdown
类的<div>
元素。
- 定位包含特定文本的
<li>
元素://li[contains(text(), '{option_text}')]
:这表示我们想要找到所有<li>
元素,这些元素的文本包含您提供的option_text
变量。{option_text}
是一个占位符,代表您想要选择的选项文本,例如“是”或“否”。
整个XPath表达式的组合用于找到包含特定文本的<label>
元素,然后定位其后的<div>
元素,该<div>
包含下拉菜单。最后,它定位并点击包含特定选项文本的<li>
元素。
请注意,XPath表达式需要根据您的网页结构和实际情况进行调整。如果您的网页结构有所不同,请相应地修改XPath表达式。
思考:
为什么不能直接用//li[contains(text(), '{option_text}')]
呢?
- 定位的准确性:
//li[contains(text(), '{option_text}')]
是一个相对宽泛的定位方式,它可能会匹配到页面上任何包含option_text
的<li>
元素,而不一定是下拉菜单中的选项。这意味着这个XPath可能会匹配到多个元素,而不是您想要点击的特定选项。 - 性能:如果页面上有多个
<li>
元素包含option_text
,那么使用这种定位方式可能会导致性能问题,因为它需要遍历更多的元素来找到匹配的元素。 - 可维护性:如果页面上
<li>
元素的布局或结构发生变化,那么使用这种定位方式可能会导致定位失败。
相比之下,使用更具体的XPath,如//label[contains(text(), '{label_text}')]/following-sibling::div//div[contains(@class, 'ivu-select-dropdown')]//li[contains(text(), '{option_text}')]
,可以确保更准确地定位到特定的选项,并且对页面的变化更加鲁棒。
总之,虽然使用//li[contains(text(), '{option_text}')]
是可行的,但它可能不如使用更具体的XPath那样准确和可靠。在实际应用中,建议根据页面的具体情况选择最合适的定位方式。