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 ‘Dimensionless units in the SI’</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>© 2015 BIPM & 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
相关产品推荐
相关产品推荐

