使用pdfminer提取PDF所有页面单词坐标时出现TypeError的原因及解决方法
解决PDFMiner提取多页面单词坐标时的TypeError问题
为什么会出现这个错误?
你碰到的TypeError: 'LTChar' object is not iterable,问题出在对PDFMiner布局元素的层级判断不够精准:
LTText是所有文本相关元素的父类,它涵盖了LTTextBox(文本框,包含多行)、LTTextLine(单行文本)这类可迭代的容器,也包含LTChar(单个字符,不可迭代)这种原子元素。- 你的原代码里,只要元素是
LTText类型就直接做for line in textbox循环,但如果这个元素本身就是一个LTChar(比如某些特殊排版的孤立字符),尝试迭代它自然会报错。
修复后的完整代码
下面的代码会严格区分不同类型的文本元素,确保能正确遍历所有页面并提取单词坐标:
from pdfminer.layout import LAParams, LTTextBox, LTTextLine, LTChar, LTAnno from pdfminer.pdfpage import PDFPage from pdfminer.pdfinterp import PDFPageInterpreter, PDFResourceManager from pdfminer.converter import PDFPageAggregator def process_char(char, current_x, current_y, current_text): """辅助函数:处理单个字符,维护当前单词的坐标和内容""" if isinstance(char, LTAnno) or char.get_text() == ' ': if current_x != -1: print(f'{repr((current_x, current_y))} : {current_text}') current_x, current_y, current_text = -1, -1, '' elif isinstance(char, LTChar): current_text += char.get_text() if current_x == -1: # 记录单词第一个字符的左上角坐标 current_x, current_y = char.bbox[0], char.bbox[3] return current_x, current_y, current_text # 初始化PDFMiner组件 fp = open('Input.pdf', 'rb') resource_manager = PDFResourceManager() laparams = LAParams() device = PDFPageAggregator(resource_manager, laparams=laparams) interpreter = PDFPageInterpreter(resource_manager, device) pages = PDFPage.get_pages(fp) # 遍历所有页面 for page_index, page in enumerate(pages, start=1): print(f"===== 第 {page_index} 页 =====") interpreter.process_page(page) layout = device.get_result() x, y, current_word = -1, -1, '' for element in layout: if isinstance(element, LTTextBox): # 文本框:遍历每一行,再遍历每个字符 for line in element: for char in line: x, y, current_word = process_char(char, x, y, current_word) elif isinstance(element, LTTextLine): # 单行文本:直接遍历每个字符 for char in element: x, y, current_word = process_char(char, x, y, current_word) elif isinstance(element, LTChar): # 单个孤立字符:直接处理 x, y, current_word = process_char(element, x, y, current_word) # 处理页面末尾未完成的单词 if x != -1: print(f'At {repr((x, y))} : {current_word}') fp.close()
关键改进点
- 精准的元素类型判断:不再笼统匹配
LTText,而是分别处理LTTextBox、LTTextLine和LTChar,避免对不可迭代的单个字符做循环操作。 - 模块化字符处理:把字符判断、单词拼接和输出的逻辑封装成辅助函数,让代码更简洁易维护。
- 页面追踪:增加了页面编号输出,方便你查看每一页的处理结果。
- 完善边界处理:确保每个页面最后一个没有以空格/换行结尾的单词也能被正确输出。
- 资源清理:最后关闭了文件句柄,避免资源泄漏。
用这个代码就能顺利处理你那24页的PDF,准确提取每个单词的左上角坐标(bbox[0]是横向坐标,bbox[3]是纵向坐标)。
内容的提问来源于stack exchange,提问作者merlin
相关产品推荐
相关产品推荐

