求助:基于标题提取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)
关键修改说明
- 替换转换器:用
PDFPageAggregator替代TextConverter,能够获取PDF的布局结构(如文本框、段落等)。 - 正确获取布局:通过
device.get_result()获取当前页面的LTPage布局对象,再遍历其子元素。 - 修复变量问题:新增
all_headings参数,传入PDF中所有标题,用于判断何时停止收集文本。 - 优化逻辑:明确标记找到目标标题的状态,遇到下一个标题时立即停止收集,避免多余内容。
内容的提问来源于stack exchange,提问作者Laxmi
相关产品推荐
相关产品推荐

