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

PyPDF2提取PDF中ZUGFeRD嵌入式XML失败问题排查

PyPDF2提取PDF中ZUGFeRD嵌入式XML失败问题排查

我明白你现在的困扰——在线工具能轻松从PDF里提取到ZUGFeRD XML,但自己用PyPDF2写的函数却一直提示“找不到嵌入式ZUGFeRD XML文件”,肯定摸不着头脑吧?咱们来一步步拆解问题,找到原因和解决办法。

你当前代码的核心问题:找错了嵌入式文件的存储位置

你现在的代码是循环每个PDF页面,在页面对象里找/EmbeddedFiles,但ZUGFeRD XML作为标准的嵌入式附件,根本不是存在页面对象里的!它的标准存储位置是在PDF文档的根字典(Root)下的/Names/EmbeddedFiles集合里,这是PDF规范中存放嵌入式文件的默认位置,在线工具也是按照这个规范查找的,而你的代码方向从一开始就错了。

另外,你的代码里还有个小bug:在循环页面的时候重复创建了pdf_reader对象,这会导致已打开的文件指针混乱,完全没必要这么做。

正确的查找逻辑:从文档根节点的Names字典入手

咱们重新梳理正确的提取流程:

  1. 打开PDF后,获取文档的根字典(通过pdf_reader.root)
  2. 检查根字典中是否存在/Names键,里面是否包含/EmbeddedFiles条目
  3. 遍历/EmbeddedFiles下的文件列表,筛选出ZUGFeRD相关的XML文件
  4. 提取该文件的原始内容并解码为字符串

修正后的代码示例

import PyPDF2

def extract_zugferd_xml(pdf_file_path):
    """
    Extracts the ZUGFeRD XML from a PDF file and returns it as a string.

    Args:
        pdf_file_path (str): The path to the PDF file to extract the XML from.

    Returns:
        str: The ZUGFeRD XML as a string.
    """
    with open(pdf_file_path, 'rb') as pdf_file:
        pdf_reader = PyPDF2.PdfReader(pdf_file)
        root = pdf_reader.root

        # 检查文档根节点是否有Names字典,且包含EmbeddedFiles
        if '/Names' not in root or '/EmbeddedFiles' not in root['/Names']:
            raise ValueError('The specified PDF file does not contain embedded files.')
        
        embedded_files_names = root['/Names']['/EmbeddedFiles']['/Names']
        # PDF的Names数组结构是 [文件名1, 文件对象1, 文件名2, 文件对象2, ...]
        for i in range(0, len(embedded_files_names), 2):
            file_name = embedded_files_names[i]
            file_obj_ref = embedded_files_names[i+1]
            # 获取文件对象的实际内容
            file_obj = pdf_reader.get_object(file_obj_ref)
            file_stream = file_obj['/EF']['/F']
            xml_content = file_stream.get_data().decode('utf-8')

            # 筛选ZUGFeRD XML:文件名通常带ZUGFeRD,或者内容里包含ZUGFeRD标识
            if (file_name.endswith('.xml') and 'ZUGFeRD' in xml_content) or 'zugferd' in file_name.lower():
                return xml_content

        # 遍历完所有嵌入式文件都没找到
        raise ValueError('The specified PDF file does not contain an embedded ZUGFeRD XML file.')

额外说明

  1. 为什么在线工具能找到?因为在线工具严格遵循了PDF规范,从文档级的嵌入式文件集合里查找,而你的代码错误地去页面对象里找,自然找不到。
  2. 少数特殊的ZUGFeRD PDF可能会把XML存放在AcroForm的嵌入式文件集合里,如果上面的代码还是找不到,可以尝试检查pdf_reader.root.get('/AcroForm', {}).get('/EmbeddedFiles'),但这种情况非常少见。

备注:内容来源于stack exchange,提问作者Djoni Djonovic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:28:11