html = """
<html>
<h2>Top Single Name</h2>
<table>
<tr>
<p>hello</p>
</tr>
</table>
<div>
<div>
<h2>Price Return</h2>
</div>
</div>
</html>
"""
当我使用下面的代码
from bs4 import BeautifulSoup
import re
soup = BeautifulSoup(html, 'html.parser')
soup.find_all(['p', 'li', 'dl', 'tr', 'div', re.compile("^h[1-6]$")])
我得到了输出
[<h2>Top Single Name</h2>,
<tr><p>hello</p></tr>,
<p>hello</p>,
<div>
<div>
<h2>Price Return</h2>
</div>
</div>,
<div>
<h2>Price Return</h2>
</div>,
<h2>Price Return</h2>]
但我需要的只是以下三个要素
[<h2>Top Single Name</h2>,
<tr><p>hello</p></tr>,
<div>
<div>
<h2>Price Return</h2>
</div>
</div>
]
基本上,我不想提取一个特定的标签,如果它在另一个标签中,我是否可以像下面这样进行一些映射,并在代码中使用--当键在值内时不要提取
{'re.compile("^h[1-6]$")': 'div', 'div':'div', 'p': 'tr'}
发布于 2022-10-26 11:32:32
--基本上我不想提取特定的标记,如果它在另一个标记中
我认为最简单的方法可能是像现在一样使用find_all
,然后通过检查嵌套标记在列表中是否有祖先/父母来筛选出嵌套标记。
sel = soup.find_all(['p', 'li', 'dl', 'tr', 'div', re.compile("^h[1-6]$")])
sel = [s for s in sel if not [p for p in sel if p in s.parents]]
-如果他们的tagName在一个列表中,如果他们的父母中没有一个有列出的名字,结果与获得标签的结果相同:
selTags = ['p', 'li', 'dl', 'tr', 'div'] + [f'h{i}' for i in range(1,7)]
sel = soup.find_all(lambda t: t.name in selTags and not t.find_parent(selTags))
但是如果你想通过地图过滤
有没有办法像下面这样进行一些映射并在代码中使用--当键在值内时不要提取
你可以用
parentMap = {'div':'div', 'p': 'tr'}
for i in range(1,7): parentMap[f'h{i}'] = 'div'
# parentMap = {'div': 'div', 'p': 'tr', 'h1': 'div', 'h2': 'div', 'h3': 'div', 'h4': 'div', 'h5': 'div', 'h6': 'div'}
sel = soup.find_all(
lambda t: t.name in
['p', 'li', 'dl', 'tr', 'div']+[f'h{i}' for i in range(1,7)]
and not (
t.name in parentMap and
t.find_parent(parentMap[t.name]) is not None
)
)
在这种情况下,无论哪种方式,都应该得到相同的结果,但是如果html包含
<p><tr>I am a row in a paragraph</tr></p>
然后,第一个方法将只返回外部<p>
标记,而最后一个方法将返回<p>
标记和内部<tr>
标记,除非将'tr': 'p'
添加到parentMap
中。
https://stackoverflow.com/questions/74212070
复制相似问题