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") 来到桌子旁,我看到了如何轻松地遍历 <tr>
标记。但是如何在 <tr>
和 <label for="Rooms"
> 中找到第二个 <td>
保存数据?
有没有比“找到唯一的一位数字的 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
属性等于Rooms
的label
标记,然后导航到其父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 单击链接