beautifulsoup表树:找到两个对象之间的所有tr?

时间:2016-03-14 06:36:33

标签: python html tree beautifulsoup html-parsing

嗨说我有这样的HTML表格(由代码中的注释自行解释):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<tbody>
    <!-- there is a box -->
    <tr>RED BOX</tr>

        <!-- containing the following balls, each <td> has a ball -->
        <!-- may be more than one <tr> -->
        <tr>
            <td>ball 1</td>
            <td>ball 2</td>
        </tr>

        <tr>
            <td>ball 3</td>
        </tr>

    <!-- another box -->
    <tr>GREEN BOX</tr>

        <!-- containing the following balls -->
        <tr>
            <td>ball 4</td>
        </tr>

</tbody>

</body>
</html>

如代码中的注释所示:RED BOX是tr,球1,2,3是RED BOX,其中球1,2,3在{{在tr之后{1}}(球可能在一个或多个<tr>RED BOX</tr>中)。 GREEN BOX是另一个tr,之后球4位于tr

我想在每个盒子里找到球。我可以通过

找到tr<tr>RED BOX</tr>
<tr>GREEN BOX</tr>

我可以使用

找到下一个tr_box = bs.findAll(text=[regex 'something BOX'])
tr

(可以找到球1,2和4,并且错过球3)

但是(1)是否有类似for t in tr_box: t[0].find_next('tr') 的内容,可以找到find_between_objectstr之间的所有<tr>RED BOX</tr>?或者某个功能会将所有<tr>GREEN BOX</tr>分成多个部分,除以tr<tr>RED BOX</tr>

(2)如何在<tr>GREEN BOX</tr>和表tr的结尾之间找到所有<tr>GREEN BOX</tr>

由于

2 个答案:

答案 0 :(得分:1)

当您遇到break的行时,

选项1: find_next_siblings()GREEN BOX

red_box = soup.find("tr", text="RED BOX")
for row in red_box.find_next_siblings("tr"):
    if row.get_text(strip=True) == "GREEN BOX":
        break

    print([td.get_text(strip=True) for td in row.find_all("td")])

itertools.takewhile()如果你想用更多的Pythonic。

选项2: a search function

def filter_rows(tag):
    return tag.name == "tr" and \
           tag.find_previous_sibling("tr", text="RED BOX") and \
           tag.find_next_sibling("tr", text="GREEN BOX")

for row in soup.find_all(filter_rows):
    print([td.get_text(strip=True) for td in row.find_all("td")])

两个选项都会打印出来:

['ball 1', 'ball 2']
['ball 3']
  

(2)如何找到GREEN BOX和表格末尾之间的所有tr?

这只是:

green_box = soup.find("tr", text="GREEN BOX")
for row in green_box.find_next_siblings("tr"):
    print([td.get_text(strip=True) for td in row.find_all("td")])

不需要在这里打破循环,find_next_siblings()当没有剩下更多匹配的兄弟姐妹时自然会停止。

仅供参考,complete gist此处。

答案 1 :(得分:0)

如果你想做的就是获得&#34;球&#34;从&#34;框&#34;,使用这种方法可能更简单。找到所有tr,然后在td s中查找所有tr

for tr in soup.find_all('tr'):
    for td in tr.find_all('td'):
        print(td.text)

打印:

ball 1
ball 2
ball 3
ball 4