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

如何从SEC 10-K HTML文档中提取Item 1板块对应的文本内容

SEC 10-K文档Item 1板块文本提取代码调整方案

原有代码问题

  • 语法混用:同时调用Scrapy的response.css方法和BeautifulSoup解析逻辑,结构混乱。且BeautifulSoup的select方法第二个参数为命名空间参数,无法用于筛选锚点属性,原有定位逻辑完全失效
  • 锚点处理错误:10-K文档内的Item跳转链接为页内锚点,不需要二次解析锚点指向的内容片段,直接在当前DOM树中查找对应锚点即可
  • 终止条件不可靠:仅通过判断Item2的父标签是否等于当前遍历标签终止遍历,会漏掉大量嵌套在其他标签内的正文内容,也容易被排版用的空白标签、换行标签打断
  • 未排除目录匹配:文本匹配未过滤目录区域的Item1条目,大概率会定位到目录的Item1链接而非正文标题

调整后实现逻辑

  1. 统一使用BeautifulSoup处理全量HTML文档,避免多套解析逻辑混用
  2. 优先定位正文区域的Item1锚点,排除目录区域的锚点,兜底方案为通过目录锚点的href属性查找正文对应锚点
  3. 定位Item2的正文锚点作为内容终止位置
  4. 从Item1锚点的父元素开始遍历所有后续元素,直到遇到Item2锚点的父元素为止,收集所有中间有效元素
  5. 统一提取收集元素的纯文本,过滤多余空白字符和无效格式

完整可运行代码

from bs4 import BeautifulSoup
import html2text
import requests

def extract_item1_text(html_content):
    soup = BeautifulSoup(html_content, 'lxml')
    # 定位Item1正文锚点,优先排除目录项
    item1_anchor = None
    for a in soup.find_all('a', string=lambda s: s and s.strip().upper() in ['ITEM 1', 'ITEM 1', 'ITEM 1.']):
        parent = a.parent
        # 正文锚点父元素通常为标题类标签,内容短,后续紧跟大段正文
        if parent.name in ['h1', 'h2', 'h3', 'font', 'b'] and len(parent.text.strip()) < 15:
            next_sib = parent.next_sibling
            while next_sib and str(next_sib).strip() == '':
                next_sib = next_sib.next_sibling
            if next_sib and len(next_sib.text.strip()) > 50:
                item1_anchor = a
                break
    # 兜底逻辑:通过目录锚点找正文锚点
    if not item1_anchor:
        for a in soup.find_all('a', string=lambda s: s and s.strip().upper() in ['ITEM 1', 'ITEM 1', 'ITEM 1.']):
            if 'href' in a.attrs and a['href'].startswith('#'):
                item_id = a['href'].lstrip('#')
                item1_anchor = soup.find('a', attrs={'name': item_id}) or soup.find('a', attrs={'id': item_id})
                break
    # 定位Item2锚点作为终止边界
    item2_anchor = None
    for a in soup.find_all('a', string=lambda s: s and s.strip().upper() in ['ITEM 2', 'ITEM 2', 'ITEM 2.']):
        if 'href' in a.attrs and a['href'].startswith('#'):
            item_id = a['href'].lstrip('#')
            item2_anchor = soup.find('a', attrs={'name': item_id}) or soup.find('a', attrs={'id': item_id})
            break
    if not item1_anchor or not item2_anchor:
        return ''
    # 收集两个锚点之间的所有有效元素
    content_elements = []
    current = item1_anchor.parent.next_sibling
    end_parent = item2_anchor.parent
    while current and current != end_parent:
        if current.name is not None:
            content_elements.append(current)
        current = current.next_sibling
    # 转换为纯文本并清洗
    h = html2text.HTML2Text()
    h.ignore_links = True
    h.ignore_images = True
    h.ignore_emphasis = True
    full_html = ''.join([str(e) for e in content_elements])
    pure_text = h.handle(full_html).strip()
    # 过滤多余空白行
    pure_text = '\n'.join([line.strip() for line in pure_text.splitlines() if line.strip()])
    return pure_text

# 调用示例
if __name__ == '__main__':
    # SEC请求需要携带合法User-Agent,否则会返回403
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}
    # 替换为目标10-K文档的URL即可
    doc_url = '替换为你的10-K文档链接'
    resp = requests.get(doc_url, headers=headers)
    item1_content = extract_item1_text(resp.text)
    print(item1_content)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 18:15:03