Python - 使用BeautifulSoup4获取父元素的第一个子元素

时间:2017-12-14 17:16:49

标签: python html beautifulsoup parent-child

我有以下HTML:

<table id="mytable">
    <tr role="row">
        <td>abc1</td>
        <td>abc2</td>
        <td>abc3</td>
        <td class="hm">Data1</td>
        <td>Data2</td>
        <td class="hm">no</td>
        <td class="hx">yes</td>
        <td class="hm">Updated</td>
    </tr>
    <tr role="row">
        <td>def1</td>
        <td>def2</td>
        <td>def3</td>
        <td class="hm">Data3</td>
        <td>Data4</td>
        <td class="hm">no</td>
        <td class="hx">no</td>
        <td class="hm">Updated</td>
    </tr>
    <tr role="row">
        <td>hij1</td>
        <td>hij2</td>
        <td>hij3</td>
        <td class="hm">Data5</td>
        <td>Data6</td>
        <td class="hm">no</td>
        <td class="hx">no</td>
        <td class="hm">Updated</td>
    </tr>
    <tr role="row">
        <td>klm1</td>
        <td>klm2</td>
        <td>klm3</td>
        <td class="hm">Data7</td>
        <td>Data8</td>
        <td class="hm">no</td>
        <td class="hx">yes</td>
        <td class="hm">Updated</td>
    </tr>
</table>

这些<tr>代码中有多个代码,因此我要执行以下操作,找到一个包含<td>标记为class="hx"且文本为yes的标记:

if (Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'})):
    print "Found 'yes'"

但我对<td>中找到的第一个<tr>标记感兴趣。我尝试了以下操作,但它似乎不起作用:

print Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).parent.find('td')[0].text

或者,下面的内容有效,但这似乎是一种非常明确的方法,特别是如果我不确定两者之间会有多少<td>个标签:

print Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).previousSibling.previousSibling.previousSibling.previousSibling.previousSibling.previousSibling.text

有更好的方法吗?我错过了什么吗?

1 个答案:

答案 0 :(得分:3)

在您的第二次印刷更改中:

find('td')[0]

为:

find('td')

Find返回第一个元素,因此无需索引。

from bs4 import BeautifulSoup

text = """
<html><head><title>Foo</title></head>
<body>
<table id="mytable">
<tr role="row">
    <td>Col1</td>
    <td>Col2</td>
    <td>Col3</td>
    <td class="hm">Data1</td>
    <td>Data2</td>
    <td class="hm">no</td>
    <td class="hx">yes</td>
    <td class="hm">Updated</td>
</tr>
<table>
"""
Soup = BeautifulSoup(text, 'html.parser')

# Will raise error
# print Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).find_parent().find('td')[0].text

print Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).find_parent().find('td').text

修改

要将第二列更改find('td')更改为find_all('td')。这将返回一个列表,您可以这样做:

td_data = Soup.find('table', {'id' : 'mytable'}).find('td', text='yes', attrs={'class' : 'hx'}).find_parent().find_all('td')
print td_data[0].text # 1st column
print td_data[1].text # 2nd column

显然,如果您的索引大于len(td_data) - 1,则会抛出IndexError