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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 21:37:33