Python Selenium 并行验证两个元素并单击一个

Python Selenium verify two elements parallelly and click on one

我是 python 的新手,我有一个问题,我有一个 table,在 table 中,有多行,在 table行有两个 table 列,一个包含文本,另一个包含按钮 我想做的是基于我想点击旁边按钮的包含文本。

HTML:

<td class="leaf" style="max-height: 40px; min-height: 40px; height: 40px;">
<table><tbody><tr>
<td class="tree-col col-lhs">
<div class="fullHeight">
<i class="fa fa-truck outsideIcon" style="position:absolute;left:6px;top:10px;"></i>
<i class="fa fa-truck innerIcon" style="color:Silver;position:absolute;left:9px;top:10px;"></i>
</div>
</td>
<td class="tree-col col-center"><div><span class="leaf-primary-name">ABC123</span><span class="leaf-subname"></span>
</div>
<div class="leaf-address">
<span>3:08 PM 3-5 Anthony rd West Ryde Zone</span>
</div>
</td>
<td class="tree-col col-rhs" style="width: 0px;"></td>
<td class="tree-col col-checkbox">
<input type="checkbox" class="k-radio" id="chk_tree_206_196_2156">
<label class="k-radio-label" for="chk_tree_206_196_2156"></label>
</td>
<td class="tree-col col-color"></td>
</tr>
</tbody>
</table>
</td>

我的操作代码如下

root_elm = "//td[@class='leaf']"
sub_elm_one = "//td/div/span"
sub_elm_two = "//input"

list_data = self.driver.find_elements_by_xpath(root_elm)
            time.sleep(5)
            for group in list_data:
                data = group.find_elements_by_xpath(sub_elm_one)
                inputs = group.find_elements_by_xpath(sub_elm_two)
                for row, radio in zip(data, inputs):
                    logging.info("Found Data : " + row.text)
                    if text in row.text:
                        radio.click()
                        logging.info("Clicked on element input :" + row.text)

当我执行这段代码时,我收到来自 radio.click() 的错误。

157, in click_element_in_element
          radio.click()
        File "e:\software installers\python\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
          self._execute(Command.CLICK_ELEMENT)
        File "e:\software installers\python\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
          return self._parent.execute(command, params)
        File "e:\software installers\python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
          self.error_handler.check_response(response)
        File "e:\software installers\python\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
          raise exception_class(message, screen, stacktrace)
      selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
        (Session info: chrome=88.0.4324.150)

当您根据其他元素查找元素时,您不应从 /// 开始 xpath 定位器,因为它们会忽略搜索上下文并从根开始。

因此,当您执行 inputs = group.find_elements_by_xpath(sub_elm_two) 时,您可能会找到一个不在您期望的组中的元素。

你的定位器应该像这样:

root_elm = "//td[@class='leaf']"
sub_elm_one = ".//td/div/span"
sub_elm_two = ".//input"

但是,如果您不需要通过验证按钮是否存在来验证文本是否存在,我建议您构建一个 xpath 来定位您的按钮相对于所需文本的位置。让 xpath 解析器来做这件事,不要自己编写逻辑。

点击与用户名关联的 <input> 标签很简单,例如ABC123你可以使用下面的:

  • XPATH中使用变量:

    username = 'ABC123'
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td[@class='leaf']//span[@class='leaf-primary-name'][text()='" +username+ "']//following::td[2]//input[@class='k-radio']"))).click()
    
  • XPATH中使用%s:

    username = 'ABC123'
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td[@class='leaf']//span[@class='leaf-primary-name'][text()='%s']//following::td[2]//input[@class='k-radio']"% str(username)))).click()
    
  • XPATH中使用format():

    username = 'ABC123'
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td[@class='leaf']//span[@class='leaf-primary-name'][text()='{}']//following::td[2]//input[@class='k-radio']".format(str(username)))).click()
    
  • 注意:您必须添加以下导入:

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

参考资料

您可以在以下位置找到一些相关的详细讨论: