beautifulsoup - beautifulsoup:在某个元素之后查找元素,不一定是兄弟姐妹或孩子
问题描述
示例 html:
<div>
<p>p1</p>
<p>p2</p>
<p>p3<span id="target">starting from here</span></p>
<p>p4</p>
</div>
<div>
<p>p5</p>
<p>p6</p>
</div>
<p>p7</p>
我想搜索<p>
s 但前提是它的位置在 之后span#target
。
在上面的示例中,它应该返回 p4、p5、p6 和 p7。
我试图先获取所有<p>
s 然后过滤,但是我也不知道如何判断一个元素是否在之后span#target
。
解决方案
您可以通过使用find_all_next
beautifulsoup 中的函数来做到这一点。
from bs4 import BeautifulSoup
doc = # Read the HTML here
# Parse the HTML
soup = BeautifulSoup(doc, 'html.parser')
# Select the first element you want to use as the reference
span = soup.select("span#target")[0]
# Find all elements after the `span` element that have the tag - p
print(span.find_all_next("p"))
上面的代码片段将导致
[<p>p4</p>, <p>p5</p>, <p>p6</p>, <p>p7</p>]
编辑:根据 OP- 比较以下位置的请求
如果要比较 2 个元素的位置,则必须依赖sourceline
和sourcepos
提供的html.parser
和html5lib
解析选项。
首先,将参考元素的sourceline
和/或存储在变量中。sourcepos
span_srcline = span.sourceline
span_srcpos = span.sourcepos
(你实际上不必存储它们,span.sourcepos
只要你有存储就可以直接span
存储)
现在遍历结果find_all_next
并比较值-
for tag in span.find_all_next("p"):
print(f'line diff: {tag.sourceline - span_srcline}, pos diff: {tag.sourcepos - span_srcpos}, tag: {tag}')
不过,您很可能对行号感兴趣,因为sourcepos
表示line 上的位置。
但是,对于每个解析器来说sourceline
,sourcepos
它们的含义略有不同。检查文档以获取该信息
推荐阅读
- flutter - 在树中引用无状态小部件
- python - 为什么我的数独求解器返回一个空的数独网格?
- python - Python:获取子进程 pid 并添加到具有父进程 id 的字典
- react-native - 如何在反应导航 5 中使用上下文提供程序包装多个堆栈屏幕?
- visual-studio - 在另一台电脑上运行时 Visual Studio 出现问题
- ios - 获取 WKwebsiteDataSource 的泄漏
- python - 选择按值加权的行索引
- android - ScrollView 和 WindowInsets
- mysql - dbeaver 未知系统变量 'query_cache_size'
- javascript - 如何使用 jquery .each() 添加单个事件侦听器?