使用 Python Selenium 遍历表行并打印列文本
Posted
技术标签:
【中文标题】使用 Python Selenium 遍历表行并打印列文本【英文标题】:Iterate through table rows and print column text with Python Selenium 【发布时间】:2015-10-27 01:12:27 【问题描述】:我有一个表 (<table>
),每行 (<tr>
) 中的值都来自其正文 (<tbody>
)。
我想打印出来的值是在<div>
标签内的<span>
。
检查 html,我看到了值,例如“名称”在第 1 行 (tr[1])、第 2 列 (td[2]):
<tr class="GAT4PNUFG GAT4PNUMG" __gwt_subrow="0" __gwt_row="0">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUHG GAT4PNUNG">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUNG">
<div __gwt_cell="cell-gwt-uid-324" style="outline-style:none;">
<span class="linkhover" title="Name" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">Name</span>
</div>
</td>
我想遍历表格的每一行并打印出第 2 列 td[2] 中的值
我正在使用 Python 和 Selenium Webdriver
表格第 1 行第 2 列的完整 Xpath 是:
html/body/div[2]/div[2]/div/div[4]/div/div[2]/div/div[3]/div/div[5]/div/div[3]/div/div[4]/div/div[2]/div/div[4]/div/div[3]/div/div[2]/div/div/table/tbody/tr[1]/td[2]/div/span
我在想是否可以从表开始,xpath如下:
html/body/div[2]/div[2]/div/div[4]/div/div[2]/div/div[3]/div/div[5]/div/div[3]/div/div[4]/div/div[2]/div/div[4]/div/div[3]/div/div[2]/div/div/table/tbody
然后我可以使用 for 循环并为 tr 和 td 使用索引 例如 row1 使用 tr[i],col2 使用 td[2]。
html/body/div[2]/div[2]/div/div[4]/div/div[2]/div/div[3]/div/div[5]/div/div[3]/div/div[4]/div/div[2]/div/div[4]/div/div[3]/div/div[2]/div/div/table/tbody/tr[i]/td[2]/div/span
我怎样才能遍历这个表并打印出始终在表的第 2 列中的 Span 类标记的值?
我试图将表格的开头放入一个变量中,然后我可以使用它来循环遍历行和列。 我需要一些帮助。
table = self.driver.find_element(By.XPATH, 'html/body/div[2]/div[2]/div/div[4]/div/div[2]/div/div[3]/div/div[5]/div/div[3]/div/div[4]/div/div[2]/div/div[4]/div/div[3]/div/div[2]/div/div/table/tbody')
这是完整的 HTML:
<table cellspacing="0" style="table-layout: fixed; width: 100%;">
<colgroup>
<tbody>
<tr class="GAT4PNUFG GAT4PNUMG" __gwt_subrow="0" __gwt_row="0">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUHG GAT4PNUNG">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUNG">
<div __gwt_cell="cell-gwt-uid-324" style="outline-style:none;">
<span class="linkhover" title="Name" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">Name</span>
</div>
</td>
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUNG">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUNG">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUNG">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUBH GAT4PNUNG">
</tr>
<tr class="GAT4PNUEH" __gwt_subrow="0" __gwt_row="1">
<td class="GAT4PNUEG GAT4PNUFH GAT4PNUHG">
<td class="GAT4PNUEG GAT4PNUFH">
<div __gwt_cell="cell-gwt-uid-324" style="outline-style:none;">
<span class="linkhover" title="Address" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">Address</span>
</div>
</td>
<td class="GAT4PNUEG GAT4PNUFH">
<td class="GAT4PNUEG GAT4PNUFH">
<td class="GAT4PNUEG GAT4PNUFH">
<td class="GAT4PNUEG GAT4PNUFH GAT4PNUBH">
</tr>
<tr class="GAT4PNUFG" __gwt_subrow="0" __gwt_row="2">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUHG">
<td class="GAT4PNUEG GAT4PNUGG">
<div __gwt_cell="cell-gwt-uid-324" style="outline-style:none;">
<span class="linkhover" title="DOB" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;color:#00A;cursor:pointer;">DOB</span>
</div>
</td>
<td class="GAT4PNUEG GAT4PNUGG">
<td class="GAT4PNUEG GAT4PNUGG">
<td class="GAT4PNUEG GAT4PNUGG">
<td class="GAT4PNUEG GAT4PNUGG GAT4PNUBH">
</tr>
<tr class="GAT4PNUEH" __gwt_subrow="0" __gwt_row="3">
---
<tr class="GAT4PNUFG" __gwt_subrow="0" __gwt_row="4">
---
</tbody>
</table>
【问题讨论】:
【参考方案1】:开发人员已将 ID 放入表中。我现在可以工作了。它正在打印第 2 列中的所有单元格值。代码是:
table_id = self.driver.find_element(By.ID, 'data_configuration_feeds_ct_fields_body0')
rows = table_id.find_elements(By.TAG_NAME, "tr") # get all of the rows in the table
for row in rows:
# Get the columns (all the column 2)
col = row.find_elements(By.TAG_NAME, "td")[1] #note: index start from 0, 1 is col 2
print col.text #prints text from the element
【讨论】:
如果thead有子tr就不行。我建议添加:tbody = table_id.find_element_by_tag_name('tbody')
【参考方案2】:
您当前使用的 XPath 相当脆弱,因为它取决于完整的文档结构和元素的相对位置。以后很容易坏掉。
相反,使用它们的class
或其他属性来定位行。例如:
for row in driver.find_elements_by_css_selector("tr.GAT4PNUFG.GAT4PNUMG"):
cell = row.find_elements_by_tag_name("td")[1]
print(cell.text)
【讨论】:
html 中有超过 1 个表,因此我使用了完整的 xpath,因此我可以获得正确的表。元素中没有 id。感谢您的建议,现在就试试吧。 @RiazLadhani 是的,这意味着您应该首先找到正确的表格(如果您需要帮助,请提供它的 HTML 代码)并在其中找到行。换句话说,使用table.find_elements_by_css_selector()
而不是driver.find_elements_by_css_selector()
。
我现在在我的问题中粘贴了一些 html。我发布 quezzie 时忘记粘贴了。我会试试 table.find_elements,谢谢。
@RiazLadhani 好,后续问题:您如何区分表格?你怎么知道这张桌子是你想要的?谢谢。
使用 firefox 检查表格单元格上的元素,其值为“Name”,我得到完整的 xpath,即:html/body/div[2]/div[2]/div/div[ 4]/div/div[2]/div/div[3]/div/div[5]/div/div[3]/div/div[4]/div/div[2]/div/div[4 ]/div/div[3]/div/div[2]/div/div/table/tbody/tr[1]/td[2]/div/span以上是关于使用 Python Selenium 遍历表行并打印列文本的主要内容,如果未能解决你的问题,请参考以下文章
Selenium web 自动化使用 python:如何使用 selenium 处理表以通过匹配文本来查找特定行并删除该行