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

rjb*_*ogz 2 html python 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>
Run Code Online (Sandbox Code Playgroud)

这些标签有多个<tr>,因此我正在执行以下操作来查找其中包含子<td>标签class="hx"且文本为 的标签yes

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

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

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

或者,以下方法可以工作,但似乎是一种非常冗长的方法,特别是如果我不确定<td>两者之间会存在多少个标签:

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

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

Har*_*pal 5

在你的第二次打印更改中:

find('td')[0]
Run Code Online (Sandbox Code Playgroud)

到:

find('td')
Run Code Online (Sandbox Code Playgroud)

查找返回第一个元素,因此不需要索引。

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
Run Code Online (Sandbox Code Playgroud)

编辑

要获得第二列,请更改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
Run Code Online (Sandbox Code Playgroud)

显然,如果你的索引大于len(td_data) - 1它会抛出一个IndexError