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

pypdf 4.2.0如何访问PDF中更多XMP元数据(如prism:doi)?

使用pypdf读取PDF的XMP元数据问题解决方案

问题描述

我使用pypdf 4.2.0版本读取PDF文件中的XMP元数据,发现通过xmp_metadata属性只能获取到dc_date等标准元数据项,很多PDF阅读器里能看到的元数据(比如示例中的prism:doi)无法读取。想请教:

  • 是否有方法访问这些额外的元数据元素?
  • 猜测XmpInformation.get_element方法可以实现,能否给出使用示例?
  • 如果pypdf做不到,还有哪些Python包可以选择?

补充:以下是《Metrologia》期刊论文的XMP元数据示例,目标是获取其中的prism:doi等信息:

<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.2-c003 61.141987, 2011/02/22-12:03:51">
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/"
 xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/" 
xmlns:xap="http://ns.adobe.com/xap/1.0/" 
xmlns:xapRights="http://ns.adobe.com/xap/1.0/rights/" 
xmlns:dc="http://purl.org/dc/elements/1.1/" 
xmlns:dcterms="http://purl.org/dc/terms/" 
xmlns:pdf="http://ns.adobe.com/pdf/1.3/" 
xmlns:prism="http://prismstandard.org/namespaces/basic/2.0/" 
xmlns:fr="http://www.crossref.org/fundref.xsd" 
xmlns="http://www.crossref.org/schema/4.3.3"
xmlns:crossmark="http://crossref.org/crossmark/1.0/">
    <rdf:Description rdf:about=""
       xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/">
    <pdfx:doi>10.1088/0026-1394/52/4/613</pdfx:doi>
    <pdfx:robots>noindex</pdfx:robots>
    <pdfx:CrossMarkMajorVersionDate>2015-8-3</pdfx:CrossMarkMajorVersionDate>
    <pdfx:CrossmarkDomainExclusive>true</pdfx:CrossmarkDomainExclusive>
    <pdfx:CrossMarkDomains><rdf:Seq><rdf:li>iop.org</rdf:li></rdf:Seq></pdfx:CrossMarkDomains>
     </rdf:Description>
    <rdf:Description rdf:about=""
       xmlns:xap="http://ns.adobe.com/xap/1.0/">
    <xap:CreatorTool>IOPP</xap:CreatorTool> 
    </rdf:Description>
    <rdf:Description rdf:about=""
       xmlns:xapRights="http://ns.adobe.com/xap/1.0/rights/">
    <xapRights:Marked>True</xapRights:Marked> 
    </rdf:Description>
      <rdf:Description rdf:about=""
            xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:format>application/pdf</dc:format>
         <dc:title>
            <rdf:Alt>
               <rdf:li xml:lang="x-default">Comment on &#x2018;Dimensionless units in the SI&#x2019;</rdf:li>
            </rdf:Alt>
         </dc:title>
         <dc:creator>
            <rdf:Seq><rdf:li>B P Leonard</rdf:li>
</rdf:Seq>
         </dc:creator>
         <dc:publisher>
            <rdf:Bag>
               <rdf:li>IOP Publishing</rdf:li>
            </rdf:Bag>
         </dc:publisher>
     <dc:identifier>doi:10.1088/0026-1394/52/4/613</dc:identifier>
     <dc:description>Metrologia, 52 (2015) 613. doi: 10.1088/0026-1394/52/4/613</dc:description>   
      </rdf:Description>
      <rdf:Description rdf:about=""
            xmlns:prism="http://prismstandard.org/namespaces/basic/2.0/">
         <prism:aggregationType>journal</prism:aggregationType>
         <prism:publicationName>Metrologia</prism:publicationName>
         <prism:copyright>&#x00A9; 2015 BIPM &amp; IOP Publishing Ltd</prism:copyright>
     <prism:issn>0026-1394</prism:issn>
         <prism:startingPage>613</prism:startingPage> 
         <prism:endingPage>616</prism:endingPage>
         <prism:pageRange>613</prism:pageRange> 
         <prism:doi>10.1088/0026-1394/52/4/613</prism:doi> 
         <prism:url>http://dx.doi.org/10.1088/0026-1394/52/4/613</prism:url>
        </rdf:Description>
    <rdf:Description rdf:about=""
       xmlns:crossmark="http://crossmark.crossref.org">
         <crossmark:MajorVersionDate>2015-8-3</crossmark:MajorVersionDate>
         <crossmark:CrossmarkDomainExclusive>true</crossmark:CrossmarkDomainExclusive>
         <crossmark:DOI>10.1088/0026-1394/52/4/613</crossmark:DOI>
         <crossmark:CrossMarkDomains><rdf:Seq><rdf:li>iop.org</rdf:li></rdf:Seq></crossmark:CrossMarkDomains>
     </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>

解决方案

1. 使用XmpInformation.get_element访问自定义元数据

XmpInformation.get_element方法可以通过命名空间URI和元素名称获取任意XMP元数据元素,正好适合获取prism:doi这类非标准字段。

示例代码:

from pypdf import PdfReader

reader = PdfReader("your_paper.pdf")
xmp = reader.metadata.xmp_metadata

# 获取prism命名空间对应的URI
prism_namespace = "http://prismstandard.org/namespaces/basic/2.0/"
# 获取prism:doi元素
prism_doi = xmp.get_element(prism_namespace, "doi")

# 输出结果
if prism_doi:
    print(f"prism:doi: {prism_doi.text}")
else:
    print("未找到prism:doi元数据")

如果要获取其他元素,比如pdfx:robots,只需替换对应的命名空间和元素名:

pdfx_namespace = "http://ns.adobe.com/pdfx/1.3/"
pdfx_robots = xmp.get_element(pdfx_namespace, "robots")
print(f"pdfx:robots: {pdfx_robots.text if pdfx_robots else '未找到'}")

2. 替代Python包推荐

如果pypdf无法满足需求,可以尝试以下工具:

  • PyMuPDF(fitz):轻量且高效,支持直接解析XMP元数据,能处理复杂的PDF结构。
    示例代码:
    import fitz
    
    doc = fitz.open("your_paper.pdf")
    xmp_data = doc.metadata.get("xmp")
    # 可以用XML解析库(如xml.etree.ElementTree)解析xmp_data提取所需字段
    
  • pdfplumber:专注于PDF内容提取,也能读取元数据,适合需要同时处理文本和元数据的场景。
  • python-xmp-toolkit:专门处理XMP数据的库,可直接解析XMP字符串,精准提取各类元数据字段。

内容的提问来源于stack exchange,提问作者Blair

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:15:54