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

如何在代码中利用pdfminer.pdffont提取PDF每个单词的字体与字号

使用pdfminer提取PDF中每个单词的字体名称及字号

嘿,我来帮你搞定这个需求!要提取PDF里每个单词的字体和字号,我们可以在你现有的布局分析代码基础上,通过遍历PDF的文本元素来获取对应的字体信息——每个字符都会关联其使用的字体和字号,我们可以把这些字符组合成单词,同时记录对应的字体属性。

关键思路

  • PDF里的文本是按LTTextBox→LTTextLine→LTChar的层级结构存储的,每个LTChar对象包含单个字符的字体名称(fontname)、字号(size)等核心信息。
  • 我们可以遍历这些元素,将连续的、字体属性一致的字符拼接成单词,最终输出每个单词及其对应的字体名称和字号。

修改后的完整代码

from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.layout import LAParams, LTTextBox, LTTextLine, LTChar

def read_pdf_miner(file_path):
    """ 
    读取PDF文件,提取每个单词的内容、字体名称及字号
    :param file_path: PDF文件路径
    :return: 包含单词信息的列表,每个元素为{"word": "", "font_name": "", "font_size": float}
    """
    word_info_list = []
    
    with open(file_path, 'rb') as file_pointer:
        parser = PDFParser(file_pointer)
        document = PDFDocument(parser)
        
        # 检查文档是否允许文本提取
        if not document.is_extractable:
            raise ValueError("该PDF文档不允许文本提取")
        
        rsrcmgr = PDFResourceManager()
        laparams = LAParams()
        # 初始化布局分析设备
        from pdfminer.converter import PDFPageAggregator
        device = PDFPageAggregator(rsrcmgr, laparams=laparams)
        interpreter = PDFPageInterpreter(rsrcmgr, device)
        
        for page in PDFPage.create_pages(document):
            interpreter.process_page(page)
            layout = device.get_result()
            
            for element in layout:
                # 遍历文本框
                if isinstance(element, LTTextBox):
                    for text_line in element:
                        # 遍历文本行
                        if isinstance(text_line, LTTextLine):
                            current_word = ""
                            current_font = None
                            current_size = None
                            
                            for char in text_line:
                                # 遍历每个字符
                                if isinstance(char, LTChar):
                                    char_text = char.get_text()
                                    # 如果是空格,说明当前单词结束
                                    if char_text.isspace():
                                        if current_word:
                                            word_info_list.append({
                                                "word": current_word,
                                                "font_name": current_font,
                                                "font_size": current_size
                                            })
                                            current_word = ""
                                    else:
                                        # 更新当前字体和字号(默认单词内字体一致)
                                        current_font = char.fontname
                                        current_size = char.size
                                        current_word += char_text
                            # 处理行尾的最后一个单词
                            if current_word:
                                word_info_list.append({
                                    "word": current_word,
                                    "font_name": current_font,
                                    "font_size": current_size
                                })
    return word_info_list

# 示例调用
if __name__ == "__main__":
    pdf_words = read_pdf_miner("example.pdf")
    for item in pdf_words:
        print(f"单词: {item['word']}, 字体名称: {item['font_name']}, 字号: {item['font_size']}")

代码说明

  • 我们通过嵌套遍历LTTextBox→LTTextLine→LTChar的层级结构,逐个获取字符的字体与字号信息。
  • 当遇到空格时,将之前拼接的字符作为一个单词存入结果列表;行尾未被空格截断的单词,在循环结束后单独处理。
  • 代码默认同一个单词内的所有字符使用相同的字体和字号,如果你的PDF存在单词内字体混合的特殊情况,可以根据需求调整逻辑(比如拆分单词分别记录)。

内容的提问来源于stack exchange,提问作者Ghaith Abu Hakmeh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:43:45