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

求助:基于标题提取PDF文本时如何修复AttributeError报错

问题描述

我需要提取PDF中指定标题对应的文本段落,例如在示例PDF中,选择标题ABSTRACT后,输出从The game到penalty area.的文本。运行代码时出现报错:AttributeError: 'PDFPageInterpreter' object has no attribute 'layout'。

原代码如下:

from pdfminer.layout import LAParams, LTTextBox
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import TextConverter
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from io import StringIO

def extract_text_under_heading(pdf_file, heading):
    output_string = StringIO()
    rsrcmgr = PDFResourceManager()
    device = TextConverter(rsrcmgr, output_string, laparams=LAParams())
    interpreter = PDFPageInterpreter(rsrcmgr, device)

    text = ""
    next_heading = None
    found_heading = False

    with open(pdf_file, 'rb') as file, StringIO() as output:
        for page in PDFPage.get_pages(file, check_extractable=True):
            interpreter.process_page(page)
            for element in interpreter.layout:
                if isinstance(element, LTTextBox):
                    if heading in element.get_text() and not found_heading:
                        found_heading = True
                        text += element.get_text()
                    elif found_heading:
                        text += element.get_text()
                        for h in headings:
                            if h in element.get_text():
                                next_heading = h
                                break
                        if next_heading:
                            break
    return text

报错信息:

AttributeError                            Traceback (most recent call last)
Cell In [3], line 1
----> 1 extract_text_under_heading(file, 'ABSTRACT')

Cell In [2], line 20, in extract_text_under_heading(pdf_file, heading)
     18 for page in PDFPage.get_pages(file, check_extractable=True):
     19     interpreter.process_page(page)
---> 20     for element in interpreter.layout:
     21         if isinstance(element, LTTextBox):
     22             if heading in element.get_text() and not found_heading:

AttributeError: 'PDFPageInterpreter' object has no attribute 'layout'
错误原因

PDFPageInterpreter没有layout属性,原代码错误地尝试从解释器获取布局结构。要解析PDF的布局元素,应该使用PDFPageAggregator而非TextConverter——TextConverter仅用于直接提取纯文本,不保留布局层级信息。此外原代码还存在headings变量未定义的问题。

修复后的代码
from pdfminer.layout import LAParams, LTTextBox
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import PDFPageAggregator
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from io import StringIO

def extract_text_under_heading(pdf_file, target_heading, all_headings):
    rsrcmgr = PDFResourceManager()
    laparams = LAParams()
    # 使用PDFPageAggregator来获取布局元素
    device = PDFPageAggregator(rsrcmgr, laparams=laparams)
    interpreter = PDFPageInterpreter(rsrcmgr, device)

    collected_text = ""
    found_target = False
    stop_collecting = False

    with open(pdf_file, 'rb') as file:
        for page in PDFPage.get_pages(file, check_extractable=True):
            interpreter.process_page(page)
            # 从device获取页面布局
            layout = device.get_result()
            for element in layout:
                if isinstance(element, LTTextBox):
                    element_text = element.get_text().strip()
                    if not found_target:
                        # 检查当前文本块是否包含目标标题
                        if target_heading in element_text:
                            found_target = True
                            # 可选:是否包含标题本身,不想要的话注释掉下面一行
                            collected_text += element_text + "\n"
                    else:
                        # 检查是否遇到下一个标题
                        if any(heading in element_text for heading in all_headings if heading != target_heading):
                            stop_collecting = True
                            break
                        # 收集文本
                        collected_text += element_text + "\n"
            if stop_collecting:
                break
    return collected_text.strip()

# 使用示例
if __name__ == "__main__":
    pdf_path = "Sample_PDF_file.pdf"
    # 传入PDF中所有可能的标题,用于识别下一个标题停止收集
    pdf_headings = ["ABSTRACT", "INTRODUCTION", "CONCLUSION"]
    result = extract_text_under_heading(pdf_path, "ABSTRACT", pdf_headings)
    print(result)
关键修改说明
  1. 替换转换器:用PDFPageAggregator替代TextConverter,能够获取PDF的布局结构(如文本框、段落等)。
  2. 正确获取布局:通过device.get_result()获取当前页面的LTPage布局对象,再遍历其子元素。
  3. 修复变量问题:新增all_headings参数,传入PDF中所有标题,用于判断何时停止收集文本。
  4. 优化逻辑:明确标记找到目标标题的状态,遇到下一个标题时立即停止收集,避免多余内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:55:16