您可以将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% 或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'})
输出:
[<td class="get_this" style="align:top"></td>]
编辑 2:简单的递归解决方案:
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 对象匹配,如果发现匹配,则元素是yielded。