Selenium/Python:查找没有其他属性的 <label for=""> 元素

Posted

技术标签:

【中文标题】Selenium/Python:查找没有其他属性的 <label for=""> 元素【英文标题】:Selenium/Python: Find <label for=""> element with no other attributes 【发布时间】:2016-06-19 13:31:07 【问题描述】:

我想恢复下表中的号码: the site

<table class="table table-hover table-inx">
 <tbody><tr>
  </tr>
  <tr>
  </tr>
  <tr>
  </tr>
  <tr>
  <td class=""><label for="RentNet">Miete (netto)</label></td>
  <td>478,28 €</td>
  </tr>
  <tr>
  </tr>
  <tr>
  </tr>
  <tr>
  <td class=""><label for="Rooms">Zimmer</label></td>
  <td>4</td>
  </tr>
  </tbody></table>

我想这种奇怪的格式是因为表格条目是可选的。我使用 driver.find_element_by_css_selector("table.table.table-hover") 来到桌子旁,我看到了如何轻松地遍历 &lt;tr&gt; 标记。但是如何在 &lt;tr&gt;&lt;label for="Rooms"> 中找到第二个 &lt;td&gt; 保存数据? 有没有比“找到唯一的一位数字的 td 字段”或加载详情页更优雅的方法?

This similar question 没有帮助我,因为有问题的标签有一个 id

编辑:

我刚刚在一个相关问题的答案中发现了一个用于 Xpath/CSS 选择器的 very helpful cheat sheet:它包含引用子/父、下一个表条目等的方法

【问题讨论】:

【参考方案1】:

您可以使用driver.find_element_by_xpath() 选择适当的td 标签。您应该使用的XPath 表达式如下:

`'//label[@for="Rooms"]/parent::td/following-sibling::td'`

这会选择for 属性等于Roomslabel 标记,然后导航到其父td 元素,然后导航到下一个td 元素。

所以你的代码将是:

elem = driver.find_element_by_xpath(
     '//label[@for="Rooms"]/parent::td/following-sibling::td')

here 是 XPath 表达式的一个示例。

【讨论】:

运行良好,xpath 摆弄网站很有帮助【参考方案2】:

使用 xpath,您可以创建对包含另一个元素的元素的搜索,如下所示:

elem = driver.find_element_by_xpath('//tr[./td/label[@for="Rooms"]]/td[2]')

elem 变量现在将保存“房间”标签行中的第二个 td 元素(这是您要查找的内容)。您还可以将 tr 元素分配给变量,然后使用行中的所有数据,因为您知道单元格结构(如果您想使用标签和数据)。

【讨论】:

【参考方案3】:

你试过 xpath 吗? Firebug 是复制 xpath 的绝佳工具。它将使用索引来选择您想要的元素。当您的元素没有名称或 ID 时,它特别有用。

编辑:不知道为什么我被否决了?我去了网站,发现 XPath Firebug 给了我:

/html/body/div[2]/div[7]/div[2]/div[3]/div/div[1]/div/div[3]/div[3]/div/table/tbody/tr[7]/td[2]

要获得 4,只需:

xpath = "/html/body/div[2]/div[7]/div[2]/div[3]/div/div[1]/div/div[3]/div[3]/div/table/tbody/tr[7]/td[2]"
elem = driver.find_element_by_xpath(xpath)

print elem.text  # prints '4'

要获取“房间”的所有元素,您可以简单地使用部分 xpath 的 driver.find_elements_by_xpath,如下所示:

xpath = "/div/div[1]/div/div[3]/div[3]/div/table/tbody/tr[7]/td[2]"
elems = driver.find_elements_by_xpath(xpath)  # returns list
for elem in elems:
    print elem.text  # prints '3', '3', '4'

最后,您也许可以通过页面源获取数据。 首先,让我们做一个函数,当我们输入页面源时输出房间列表:

def get_rooms(html):
    rooms = list()
    partials = html.split('''<label for="Rooms">''')[1:]
    for partial in partials:
        partial = partial.split("<td>")[1]
        room = partial.split("</td>")[0]
        rooms.append(room)
    return rooms

一旦我们定义了该函数,我们就可以通过以下方式检索房间号列表:

html = driver.page_source
print get_rooms(html)

它应该输出:

["3", "3", "4"]

【讨论】:

我没有对你投反对票,但是虽然 XPath 有它的位置,但像 "/html/body/div[2]/div[7]/div[2]/div[3] 这样的选择器/div/div[1]/div/div[3]/div[3]/div/table/tbody/tr[7]/td[2]" 没有语义信息并且非常脆弱 - 这使得不好的测试。 Chrome 和 FF 可以为我们生成选择器,这很好,但有时它们绝对很糟糕。 我明白 100%。我只是在使用 Firebug 给我的 XPath,对于不熟悉 XPath 语义但想要编写自己的程序的初学者来说,这可能是一个有用的工具。毫无疑问,学习 XPath 比不断依赖 Firebug 更好。 我也没有投反对票。我对您的示例的问题是假设标签将始终存在。我相信可能存在越界错误?

以上是关于Selenium/Python:查找没有其他属性的 <label for=""> 元素的主要内容,如果未能解决你的问题,请参考以下文章

AttributeError:“WebElement”对象没有属性“单击”错误尝试使用 Selenium Python 单击链接

selenium3 + python - xpath定位

selenium python 处理alter

按值查找元素 Selenium/Python

使用 Python selenium 查找 href 链接

selenium python怎么封装方法