如何通过表格中的部分文本查找元素,每行有多行和单元格?

Posted

技术标签:

【中文标题】如何通过表格中的部分文本查找元素,每行有多行和单元格?【英文标题】:How to find element via partial text within table with multiple rows and cells per row? 【发布时间】:2018-06-12 09:54:40 【问题描述】:

我的目标是让 Selenium 多次单击隐藏在表格中的许多行和单元格中的“禁用”链接。

我正在从 Excel 电子表格中读取以获取 "P#####" 的值(它始终是 2nd )以进行循环。这些都是部分文本。 P#####之后的“随机词”,我不知道。所以我需要能够通过部分文本找到元素,我认为这是我在自己的代码中完成的,但我无法验证该部分是否正常工作。

大约有 1000 行,我不需要全部访问它们。 a href 标记的 ID 后面有与 P##### 值不对应的随机数。

这是 html 的样子(不是真实的):

<tbody>
  <tr>
    <td>1.</td>
    <td>P12345 randomwordshere</td>
    <td>..</td>
    <td>..</td>
    <td>
      <ul>
        <li>..</li>
        <li>..</li>
        <li><a id="disable_###" href="link">Disable</a></li>
      </ul>
    </td>
  </tr>
  <tr>
    <td>2.</td>
    <td>P23456 otherrandomwords</td>
    <td>..</td>
    <td>..</td>
    <td>
      <ul>
        <li>..</li>
        <li>..</li>
        <li><a id="disable_###" href="link">Disable</a></li>
      </ul>
  </tr>
  <tr>..</tr>
  <tr>..</tr>
  <tr>..</tr>
  <tr>..</tr>
  <tr>..</tr>
  <tr>..</tr>
  <tr>..</tr>
</tbody>

这是我的 python 代码的一部分,到目前为止没有成功。

for x in range(0, num_rows):
  value = str(sheet.cell(x, 0))
  pcode = value[7:len(value) - 1]
  browser.implicitly_wait(10)
  browser.find_element_by_xpath("//*[contains(text(), '" + pcode + "')]")
  browser.find_element_by_xpath("//td/ul/li[contains(@id, 'disable')]").click() #this part is definitely wrong

那么如何在我拥有的相同 P#### 值的行中找到每个禁用链接?

【问题讨论】:

那么,你的问题是什么? @AmosEgel 抱歉,不清楚。如何根据我拥有的每个 P#### 值找到每个禁用链接?他们在同一行,但我不知道如何做任何事情。 只是观察,但您的 HTML 格式不正确(无效)这可能会弄乱您的 XPATH 您可以尝试格式正确的 HTML 吗? @Dan-Dev 我放在那里的 HTML 只是我正在查看的一个示例,我对 HTML 没有任何控制权,所以这就是我必须处理的解决方法。 如果您从 Excel 电子表格中读取 HTML,您可以先将其通过 HTML tidy 吗?但我的意思是,如果我们知道它是由于无效的 HTML 造成的,那么我们就知道从哪里开始。 【参考方案1】:

您需要找到 pcode,然后执行以下操作以找到禁用。您当前的做法是丢弃第一个 find_element。

这些方面的东西应该可以工作(它对我有用)。我认为对于python来说它是跟随兄弟。

(//*[contains(., 'P')]/following::li/a[contains(@id, 'disable')])[i]

将您的 pcode 放在 'P' 所在的位置,然后使用 for 循环递增结果,这就是 '[i]' 的索引在最后。

显然,您需要自己进行编辑,因为我们没有完整的代码来给出完整的答案,但这应该会让您开始走上正确的道路。

【讨论】:

pcode = value[7:len(value) - 1] for i in range(0,1200): browser.find_element_by_xpath("//*[contains(., '" + pcode + " ')]/following::li/a[contains(@id, 'disable')])[i](//*[contains(., '" + pcode + "')]/following::li/a [contains(@id, 'disable')]")[i].click() 它说表达式是非法的。我正在从电子表格中获取 pcode,因此您可以忽略第一行。我不确定这个 for 循环是否符合您的想法,我不熟悉语句末尾的 i 。但我还必须为语法添加一些“”。抱歉,正在尝试修复格式 为什么要加倍 xpath?它应该只是browser.find_element_by_xpath("(//*[contains(., '" + pcode + "')]/following::li/a[contains(@id, 'disable')])[i].click()") 打开一个浏览器控制台,看看你是否可以通过这个(//*[contains(., 'P')]/following::li/a[contains(@id, 'disable')])找到该元素。你会看到它显示了多个发现。这就是增量的用途。 糟糕,我必须粘贴两次,我的错误。我修复了它,这是新的错误:selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //*[contains(., 'P000001 - Database')]/following::li/a[contains( @id, '禁用')] 打开浏览器控制台,看看能否通过(//*[contains(., 'P000001 - Database')]/following::li/a[contains(@id, 'disable')])找到元素【参考方案2】:

您可以使用 XPath 来做到这一点。

//td[contains(.,'P12345')]//following::a[starts-with(@id,'disable_')]

此 XPath 会查找包含您的 P# 的 TD,然后查找 ID 以“disable_”开头的第一个 A 标记。

您需要在每个循环中将“P12345”替换为 Excel 中的值。这将返回所有禁用链接。只要你使用find_element(),它总是会返回你想要的第一个。

【讨论】:

【参考方案3】:

首先,使用下面的模式找到包含 pcode 的 tr:

//tr[td[contains(text(), 'Database')]] 假设这里的 pcode 是 'Database'

然后从找到的 tr 中找到“禁用”链接,如下所示:

//tr[td[contains(text(), 'Database')]]//a[text()='Disable']

试试下面的代码:

for x in range(0, num_rows):
  value = str(sheet.cell(x, 0))
  pcode = value[7:len(value) - 1]
  browser.implicitly_wait(10)
  browser.find_element_by_xpath("//tr[td[contains(text(), '" + pcode + "')]]//a[text()='Disable']").click()

【讨论】:

以上是关于如何通过表格中的部分文本查找元素,每行有多行和单元格?的主要内容,如果未能解决你的问题,请参考以下文章

如何将excel表格中多行的部分数据分别提取到另一表格中指定的多行固定位置?

如何在编辑表格视图单元格中的文本字段时重新加载所有表格视图单元格 - iOS Swift

excel表格怎么提取单元格中的部分内容

从 PyQt 中的表格小部件中选择多行后,单元格小部件(按钮)显示在错误的位置

单个 UITableview 单元格中的多种字体大小 (Swift)

delphi DBgridEh多行单元格如何实现~急!!