You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

企业年报PDF爬虫开发求助:关键词数据提取方案

高效提取企业年报PDF中营收、利润数据的可行策略

Hey Robin, 针对你爬取企业年报PDF并提取REVENUE、PROFIT这类关键数值到DataFrame的需求,我整理了几个经过实践验证的高效方案,解决你之前用tabula-py、PyPDF2遇到的效率问题:


1. 正则表达式(Regex)+ 文本提取(适合纯文本场景)

既然你已经能把PDF转成TXT,那正则是最直接的工具,重点是写能匹配年报中数值格式的正则规则——毕竟年报里的数值通常带千位分隔符、货币符号,位置也可能灵活。

示例代码:

import re
import pandas as pd

# 读取转换好的TXT文件
with open("annual_report.txt", "r", encoding="utf-8") as f:
    text = f.read()

# 匹配关键词(支持大小写)+ 数值(适配千位分隔符、货币符号)
pattern = r"(?i)(revenue|profit)\s*[:\-]?\s*([\d.,]+)\s*([€$£]|EUR|USD|GBP)?"
matches = re.findall(pattern, text)

# 整理成DataFrame
results = pd.DataFrame(matches, columns=["Metric", "Value", "Currency"])
# 清洗数值(统一千位分隔符和小数点)
results["Cleaned_Value"] = results["Value"].str.replace(".", "", regex=False).str.replace(",", ".", regex=False).astype(float)

优化点:

  • 正则里的(?i)忽略大小写,能匹配REVENUERevenuerevenue等变体
  • 适配不同的数值格式:比如1.000.000.000€1,000,000$1000000 EUR
  • 可以扩展关键词列表,比如加上Net ProfitGross Revenue

2. 优化Tabula-py的表格提取逻辑(适合表格密集的年报)

年报里的核心数据大多在表格里,之前用tabula没效果可能是参数没调对。Tabula有两种模式:lattice(适合带边框的表格)和stream(适合无边框的表格),可以结合使用。

示例代码:

import tabula
import pandas as pd

# 读取PDF所有页面的表格,自动识别模式
dfs = tabula.read_pdf(
    "annual_report.pdf",
    pages="all",
    guess=True,  # 自动判断表格模式
    multiple_tables=True,
    encoding="utf-8"
)

# 合并所有表格,筛选包含目标关键词的行
combined_df = pd.concat(dfs, ignore_index=True)
# 模糊匹配关键词(支持大小写)
target_rows = combined_df[combined_df.apply(lambda row: row.astype(str).str.contains(r"(?i)revenue|profit").any(), axis=1)]

# 提取数值列(可根据实际表格结构调整)
final_results = target_rows.melt(id_vars=[col for col in target_rows.columns if "description" in col.lower()], 
                                 value_vars=[col for col in target_rows.columns if "amount" in col.lower() or col.isnumeric()],
                                 var_name="Metric_Type", value_name="Value")

优化点:

  • pages="all"批量提取所有页面的表格
  • 如果知道目标表格在特定页面,直接指定pages="5-10"提升效率
  • 对于复杂表格,可以用area参数指定表格的坐标(Tabula的GUI工具可以帮你获取坐标)

3. 用PyMuPDF(fitz)替代PyPDF2(精准文本定位)

PyMuPDF比PyPDF2的文本提取精度更高,还能获取文本的位置信息——可以通过关键词的位置,提取其附近的数值,避免纯正则的误匹配。

示例代码:

import fitz
import re
import pandas as pd

doc = fitz.open("annual_report.pdf")
matches = []

for page in doc:
    # 搜索关键词(支持大小写)
    text_instances = page.search_for("revenue", hit_max=10) + page.search_for("profit", hit_max=10)
    for inst in text_instances:
        # 提取关键词周围的文本(比如右侧和下方的区域)
        surrounding_text = page.get_textbox(fitz.Rect(inst.x0, inst.y0, inst.x1+200, inst.y1+50))
        # 用正则提取数值
        num_match = re.search(r"([\d.,]+)\s*([€$£]|EUR|USD|GBP)?", surrounding_text)
        if num_match:
            matches.append({
                "Page": page.number+1,
                "Metric": inst.get_text().strip(),
                "Value": num_match.group(1),
                "Currency": num_match.group(2) if num_match.group(2) else None
            })

doc.close()
results_df = pd.DataFrame(matches)

优势:

  • 能精准定位关键词在页面的位置,提取更相关的数值
  • 支持提取特定区域的文本,减少无关内容的干扰

4. 结合LLM辅助提取(处理复杂格式的终极方案)

如果年报格式非常多样化,正则和表格提取都搞不定,可以试试用大语言模型(比如GPT-3.5/4)来结构化提取。把提取的文本或表格片段传给模型,让它直接返回JSON格式的结果,再转成DataFrame。

示例代码(伪代码):

import openai
import pandas as pd
import json

# 假设已经提取了页面文本
page_text = "..."  # 从PDF中提取的文本片段

prompt = f"""
请从以下企业年报文本中提取所有REVENUE、PROFIT相关的数值,返回JSON格式,包含字段:Metric, Value, Currency。
文本内容:{page_text}
"""

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": prompt}]
)

# 解析JSON结果到DataFrame
results = json.loads(response.choices[0].message.content)
results_df = pd.DataFrame(results)

注意事项:

  • 要注意数据隐私,不要把敏感的年报内容传给公开API
  • 可以批量处理文本片段,降低API调用成本

总结建议

实际处理年报时,建议组合使用多种方法

  1. 先用PyMuPDF或Tabula提取所有文本和表格
  2. 用正则初步筛选关键词和数值
  3. 对复杂格式的内容,用LLM辅助补全

这样既能保证效率,又能覆盖大部分年报的格式差异。

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

火山引擎 最新活动