如何使用Beautiful Soup 4来查找属性

时间:2016-04-23 00:15:09

标签: python html parsing attributes beautifulsoup

我正在尝试解析html,如下所示:

<tbody>
    <tr class data-row="0">
        <td align="right"></td>
    </tr>
    <tr class data-row="1">
        <td align="right"></td>
    </tr>
    <tr class="thead over_theader" data-row="2">
        <td align="right"></td>
    </tr>
    <tr class="thead" data-row="3">
        <td align="right"></td>
    </tr>
    <tr class data-row="4">
        <td align="right"></td>
    </tr>
    <tr class data-row="5">
        <td align="right"></td>
    </tr>
</tbody>

我想获取未指定tr的所有class代码(及其子代)。对于上面的示例,这意味着我希望tr标记data-row不是2或3。

如何使用Beautiful Soup 4进行​​此操作?

我试过

tableBody = soup.findAll('tbody')
rows = tableBody[0].findAll(attrs={"class":""})

但是当我想要bs4.element.ResultSet长度为4(一个用于tr时,这会返回一个长度为8的td类型(即包含bs4.element.ResultSettr子项的子项)每个class = ""代码都带有www)。

2 个答案:

答案 0 :(得分:0)

当我指定tr标记名称时,您的方法实际上适用于我:

>>> from bs4 import BeautifulSoup
>>> data = """
... <tbody>
...     <tr class data-row="0">
...         <td align="right"></td>
...     </tr>
...     <tr class data-row="1">
...         <td align="right"></td>
...     </tr>
...     <tr class="thead over_theader" data-row="2">
...         <td align="right"></td>
...     </tr>
...     <tr class="thead" data-row="3">
...         <td align="right"></td>
...     </tr>
...     <tr class data-row="4">
...         <td align="right"></td>
...     </tr>
...     <tr class data-row="5">
...         <td align="right"></td>
...     </tr>
... </tbody>
... """
>>> soup = BeautifulSoup(data, "html.parser")
>>> len(soup.find_all("tr", class_=""))
4

或者,您可以使用tr[class=""] CSS selector

>>> len(soup.select('tr[class=""]'))
4

答案 1 :(得分:0)

默认情况下,

find_all将递归搜索。因此td代码是有效匹配。

Docs

  

如果你致电mytag.find_all(),美丽的汤将检查mytag的所有后代:它的孩子,孩子的孩子,等等。如果你只想要美丽的汤来考虑直接孩子,你可以传递recursive=False

所以你可以写一下,例如:

tableBody = soup.findAll('tbody')
rows = tableBody[0].find_all(attrs={"class":""}, recursive=False)

print(len(rows))
for r in rows:
    print('---')
    print(r)

输出:

4
---
<tr class="" data-row="0">
<td align="right"></td>
</tr>
---
<tr class="" data-row="1">
<td align="right"></td>
</tr>
---
<tr class="" data-row="4">
<td align="right"></td>
</tr>
---
<tr class="" data-row="5">
<td align="right"></td>
</tr>