使用Python Selenium循环遍历表格行并打印列文本

27

我有一个带值的表格(<table>),每一行(<tr>)都有值,这些值在其主体(<tbody>)中。

我想打印出的值位于<div>标签内的<span>中。

检查html,我看到例如“Name”这个值位于第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>
我想循环遍历表格的每一行并打印出第二列的值,即td[2]。
我正在使用带有Selenium Webdriver的Python。
表格第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使用索引。例如,对于第一行使用tr[i],对于第二列使用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

我该如何循环遍历这个表并打印出位于表格第二列的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>
3个回答

48

开发者在表格中插入了一个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

9
如果 thead 元素有子元素 tr,这段代码将无法正常运行。我建议添加以下代码:tbody = table_id.find_element_by_tag_name('tbody') - Piotr Pęczek

21

您目前使用的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中有不止一个表格,因此我使用了完整的XPath以便获取正确的表格。元素中没有ID。感谢您的建议,我现在正在尝试它。 - Riaz Ladhani
@RiazLadhani 是的,这意味着你应该先找到正确的表格(如果需要帮助,请提供其HTML代码),然后在其中查找行。换句话说,使用 table.find_elements_by_css_selector() 而不是 driver.find_elements_by_css_selector() - alecxe
我现在已经将一些HTML粘贴到我的问题中了。当我发布quezzie时,我忘记粘贴了。我会尝试使用table.find_elements,谢谢。 - Riaz Ladhani
@RiazLadhani 很好,接下来的问题是:你如何区分不同的表格?你怎么知道这个表格是所需的表格?谢谢。 - alecxe
我得到了以下输出[<selenium.webdriver.remote.webelement.WebElement object at 0x01A5B690>, <selenium.webdriver.remote.webelement.WebElement object at 0x01A5B5F0>, <selenium.webdriver.remote.webelement.WebElement object at 0x01A5B390>, - Riaz Ladhani
显示剩余8条评论

0
可能有点晚了。但这是我的代码,而且运行得很好。
def find_in_table(self, name):
        check_table = self.isElementPresent("//table[@class='assessment_list_table_tableStyle__Qw-rz']",
                                            locatorType="xpath")
        while not check_table:
            time.sleep(10)
            check_table = self.isElementPresent("//table[@class='assessment_list_table_tableStyle__Qw-rz']",
                                                locatorType="xpath")

        table_id = self.driver.find_element(By.XPATH, "//table[@class='assessment_list_table_tableStyle__Qw-rz']")
        rows = table_id.find_elements(By.TAG_NAME, "tr")
        for x in range(1, len(rows)):
            col = rows[x].find_elements(By.TAG_NAME, "td")[0]
            s = col.text
            if s == name:
                return x
  1. 检查表是否存在
  2. 使用find_elements获取表ID
  3. 使用表ID查找表中的行
  4. 遍历表格并在第一列(0)中查找文本
  5. 当文本与列中的文本匹配时,返回行值

可以使用IntelliJ中的selenium插件获取表元素的XPATH。该插件非常有用,可以查找元素,并且比浏览器扩展中的插件更准确。

(isElementPresent方法是我使用selenium的getElement方法检查元素是否存在并返回布尔值的方法)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接