You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于CEO_PAY_RATIO标签提取至指定hr标签间的HTML内容?

解决BeautifulSoup提取嵌套标签区间内容的问题

我需要提取HTML中从name属性为CEO_PAY_RATIO的<a>标签起始,到style包含width:100%的<hr>标签结束区间内的内容。但现有两段基于BeautifulSoup的Python代码,在<a>标签嵌套在<p>等标签内时,仅能提取到“CEO PAY RATIO”,无法获取后续的目标内容,求解决方法。


初始提取函数

def extract_content(soup, name):
    tag = soup.find('a', {'name': name})
    all_breaks = soup.select('hr[style*="width:100%"]')

    content = ""
    if tag:
        current_tag = tag.find_next()
        print(len(all_breaks))
        while current_tag and not (current_tag.name == 'hr' and current_tag in all_breaks):
            content += current_tag.get_text().strip() + " "
            current_tag = current_tag.find_next()

    return content.strip()

测试代码

soup = BeautifulSoup(html_text, "html.parser")

# 预处理文档(移除<font>标签)
for font in soup.select("font"):
    font.unwrap()

soup.smooth()

# 查找目标标签
tag = soup.find('a', {'name':"CEO_PAY_RATIO"})

text = []
while tag := tag.next_sibling:
    if tag.name == "hr" and "width:100%" in tag.attrs.get("style", ""):
        break
    t = tag.get_text(strip=True, separator=" ")
    if t:
        text.append(t)

text = "\n".join(text)
print(text)

目标HTML片段

<p style="margin-bottom:0pt;margin-top:0pt;text-indent:0%;font-weight:bold;color:#0061F0;font-size:22pt;font-family:Segoe UI;text-transform:uppercase;font-style:normal;font-variant: normal;"><a name="_AEIOULastRenderedPageBreakAEIOU209">
<a name="CEO_PAY_RATIO"></a><font style="font-weight:bold;color:#0061F0;font-size:22pt;
font-family:Segoe UI;text-transform:uppercase;font-style:normal;font-variant: normal;">
<a name="CEO_PAY_RATIO"></a>CEO PAY</font><font style="font-weight:bold;color:#0061F0;font-size:22pt;
font-family:Segoe UI;text-transform:uppercase;font-style:normal;font-variant: normal;"> RATIO</font></p>
<some other stuff>
<hr style="page-break-after:always;width:100%;"/>
<some other we don't want>

问题根源

两段代码的核心缺陷:

  • 初始函数用tag.find_next()仅遍历当前标签的子节点和同级后续节点,无法跳出<p>标签获取外部内容;
  • 测试代码用tag.next_sibling只遍历当前标签的同级兄弟节点,同样无法触及<p>之后的元素。

修复后的代码

from bs4 import BeautifulSoup

def extract_target_content(soup):
    # 定位起始<a>标签(取第一个匹配项)
    start_tag = soup.find('a', {'name': 'CEO_PAY_RATIO'})
    if not start_tag:
        return ""
    
    # 定位终止<hr>标签
    end_tag = soup.find('hr', style=lambda s: s and 'width:100%' in s)
    if not end_tag:
        return ""
    
    content = []
    current_node = start_tag
    while current_node:
        # 遇到终止标签则停止遍历
        if current_node is end_tag:
            break
        # 提取元素节点的有效文本
        if current_node.name:
            text = current_node.get_text(strip=True, separator=" ")
            if text:
                content.append(text)
        # 遍历文档流中的下一个节点(跨层级)
        current_node = current_node.next_element
    
    return "\n".join(content)

# 使用示例
soup = BeautifulSoup(html_text, "html.parser")

# 预处理移除font标签
for font in soup.select("font"):
    font.unwrap()

result = extract_target_content(soup)
print(result)

代码说明

  1. 用next_element替代原有的遍历方法:该方法会遍历文档流中的下一个节点,不受层级限制,能跳出<p>标签获取后续内容;
  2. 直接通过节点对象判断终止条件,避免重复查找;
  3. 保留文本过滤逻辑,仅收集非空有效文本。

内容的提问来源于stack exchange,提问作者ken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 19:44:59