我正在尝试解析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.ResultSet
个tr
子项的子项)每个class = ""
代码都带有www
)。
答案 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>