【问题标题】:Selenium finds element from the entire page instead of just a part of it (Python)Selenium 从整个页面中查找元素,而不仅仅是其中的一部分(Python)
【发布时间】:2021-07-31 01:52:07
【问题描述】:

我有一个像这样的 html 元素:

<table>
   <tbody>
      <tr>
         <td>My Text</td>
         <td>Some Other Text</td>
         <td><img src="../delete.png" alt="trashcan"></td>
      </tr>
      <tr>
         <td>More Text</td>
         <td>Some More Text</td>
         <td><img src="../delete.png" alt="trashcan"></td>
      </tr>
   </tbody>
</table>

我想逐行查找表格,然后点击垃圾桶图标将其删除。

所以我的想法是遍历行&lt;tr/&gt;,然后遍历单元格&lt;td/&gt;。如果文本与单元格文本匹配,则从该行中找到XPATH 的图像,然后单击它。

tbody = driver.find_element_by_tag_name("tbody")
tr = tbody.find_elements_by_tag_name("tr")
for row in tr:
   td = row.find_elements_by_tag_name("td")
   print(len(td))
   for cell in td:
     if cell.text == "More Text":
       delete = row.find_element_by_xpath('//img[@alt="trashcan"]')
       delete.click()

我的理解是driver是整个页面。 tbody 只是该页面中的 tbody 元素。因此,无论我试图从那里找到什么,都必须是该元素的子元素。为了确认我打印出 td 元素的长度,即打印出“3”。

删除按钮delete = row.find_element_by_xpath('//img[@alt="trashcan"]') 从第一行而不是第二行选择删除按钮。

我也试过

delete = row.find_elements_by_xpath('//img[@alt="trashcan"]')
delete[0].click()

但它也选择了行。

只是为了确保我在 if 条件下打印出该行(print(row.get_attribute("innerHTML")) 并打印出第二行。

有什么想法或者我可以如何选择第二行中的img 吗?

【问题讨论】:

标签: python selenium selenium-webdriver web-scraping xpath


【解决方案1】:

您可以使用 text() 方法找到正确的 XPath,如下所示:

//td[contains(text(),'Some More Text')]/../td[3]

或者:

//td[contains(text(),'Some More Text')]/parent::tr/td[3]

第一个只是向上一级,然后寻找第三个 td 元素。

第二种方法查看父元素,如XPath: Get parent node from child node 所述。

尝试将其应用到您的循环中。

【讨论】:

    【解决方案2】:

    find_element_by_xpath 只会给你它找到的第一条路径。

    我不确定您对 JavaScript 的熟悉程度,但我倾向于使用 find_elements_by_css_selector。然后,它允许您输入与运行 document.querySelectorAll 时相同的参数。

    在你的情况下,你可以这样做:

    text_to_find = 'If this is spotted, then delete'
    # Find all tds
    trs = driver.find_elements_by_css_selector("td")
    # Iterate over each tr insde a td.
    for tr in trs:
        for td in tr.find_elements_by_css_selector('tr'):
            # If any td text is equal to the text you wish to delete, then click on the trashcan and then move onto the next td.
            if td.text == text_to_find:
                tr.find_element_by_css_selector("[alt='trashcan']").click() # notice that I removed the 's' in elements.
                break
    

    【讨论】:

      【解决方案3】:

      您可以尝试更改 for 循环。喜欢for i in range(1,len(tr)): 它跳过第一个tr。 或者你可以在 for 循环之前 pop tr 中的第一个元素。

      【讨论】:

      • 只有在值被硬编码的情况下才有效,表格实际上会随着更多的输入而改变,无论如何谢谢
      猜你喜欢
      • 1970-01-01
      • 2018-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多