我正在尝试使用beautifulsoup来解析网站上的表格。 (我无法共享网站源代码,因为它是限制使用的。)
我正在尝试仅在具有以下两个具有这些特定类的标记时提取数据。
td, width=40%
tr, valign=top
我这样做的原因是提取具有这些标签和类的数据。
我发现了一些关于使用多个标签here的讨论,但这个只讨论标签而不是类。但是,我确实尝试使用相同的使用列表的逻辑来扩展代码,但我认为我得到的并不是我想要的:
my_soup=soup.find_all(['td',{"width":"40%"},'tr',{'valign':'top'}])
总结一下,我的查询是如何在find_all中使用多个标签,每个标签都有一个特定的类,以便结果' ands'两个标签。
答案 0 :(得分:0)
让我们说bsObj是你美丽的汤对象 尝试:
tr = bsObj.findAll('tr', {'valign': 'top'})
td = tr.findAll('td', {'width': '40%'})
希望这有帮助。
答案 1 :(得分:0)
您可以将re.compile
对象与soup.find_all
一起使用:
import re
from bs4 import BeautifulSoup as soup
html = """
<table>
<tr style='width:40%'>
<td style='align:top'></td>
</tr>
</table>
"""
results = soup(html, 'html.parser').find_all(re.compile('td|tr'), {'style':re.compile('width:40%|align:top')})
输出:
[<tr style="width:40%">
<td style="align:top"></td>
</tr>, <td style="align:top"></td>]
通过提供re.compile
对象来指定所需的标记和style
值,find_all
将返回包含内联的tr
或td
标记的任何实例style
或width:40%
的{{1}}属性。
可以通过提供多个属性值来推断此方法以查找元素:
align:top
输出:
html = """
<table>
<tr style='width:40%'>
<td style='align:top' class='get_this'></td>
<td style='align:top' class='ignore_this'></td>
</tr>
</table>
"""
results = soup(html, 'html.parser').find_all(re.compile('td|tr'), {'style':re.compile('width:40%|align:top'), 'class':'get_this'})
编辑2:简单的递归解决方案:
[<td class="get_this" style="align:top"></td>]
输出:
import bs4
from bs4 import BeautifulSoup as soup
def get_tags(d, params):
if any((lambda x:b in x if a == 'class' else b == x)(d.attrs.get(a, [])) for a, b in params.get(d.name, {}).items()):
yield d
for i in filter(lambda x:x != '\n' and not isinstance(x, bs4.element.NavigableString) , d.contents):
yield from get_tags(i, params)
html = """
<table>
<tr style='align:top'>
<td style='width:40%'></td>
<td style='align:top' class='ignore_this'></td>
</tr>
</table>
"""
print(list(get_tags(soup(html, 'html.parser'), {'td':{'style':'width:40%'}, 'tr':{'style':'align:top'}})))
递归函数使您能够为自己的字典提供某些标签的所需目标属性:此解决方案尝试将任何指定的属性与传递给函数的[<tr style="align:top">
<td style="width:40%"></td>
<td class="ignore_this" style="align:top"></td>
</tr>, <td style="width:40%"></td>]
对象进行匹配,以及是否找到匹配项,则该元素是bs4
版。