在Python中读取PDF属性/元数据

Kha*_*eel 34 python pdf metadata

如何使用Python读取存储在PDF文件中的标题,作者,主题和关键字等属性/元数据?

nam*_*mit 38

试试pdfminer:

from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument

fp = open('diveintopython.pdf', 'rb')
parser = PDFParser(fp)
doc = PDFDocument(parser)

print(doc.info)  # The "Info" metadata
Run Code Online (Sandbox Code Playgroud)

这是输出:

>>> [{'CreationDate': 'D:20040520151901-0500',
  'Creator': 'DocBook XSL Stylesheets V1.52.2',
  'Keywords': 'Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free',
  'Producer': 'htmldoc 1.8.23 Copyright 1997-2002 Easy Software Products, All Rights Reserved.',
  'Title': 'Dive Into Python'}]
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅本教程:一个轻量级XMP解析器,用于在Python中提取PDF元数据.

  • 截至2013年11月,"PDFDocument类现在将PDFParser对象作为参数.将删除PDFDocument.set_parser()和PDFParser.set_document()." 所以你可以做doc = PDFDocument(解析器),并跳过对set_document,set_parser和initialize的调用. (9认同)
  • 现在有一个项目的官方Python 3分支https://github.com/pdfminer/pdfminer.six (2认同)

Mor*_*mer 12

对于Python 3,请参阅PyPDF2,其中来自@Khaleel的示例代码更新为:

from PyPDF2 import PdfFileReader
pdf_toread = PdfFileReader(open("test.pdf", "rb"))
pdf_info = pdf_toread.getDocumentInfo()
print(str(pdf_info))
Run Code Online (Sandbox Code Playgroud)

安装使用pip install PyPDF2.


par*_*vus 8

pikepdf提供了一种简单可靠的方法来做到这一点。

我用一堆 pdf 文件对此进行了测试,似乎有两种不同的方法可以在创建 PDF 时插入元数据。有些正在插入NUL字节和其他乱码。Pikepdf 可以很好地处理这两个问题。

import pikepdf
p = pikepdf.Pdf.open(r'path/to/file.pdf')
str(p.docinfo['/Author'])  # mind the slash
Run Code Online (Sandbox Code Playgroud)

这将返回一个字符串 - 如果您用str. 例子:

  • 'Normal person'
  • 'ABC'

与其他选项比较:

  • pdfminer - 未积极维护
  • pdfminer.6 - 活跃
  • pdfreader - 活动(但仍然建议您使用easy_install,ao)
  • pypdf - 活动。
  • PyPDF2 - 被合并回 pypdf。PyPDF2==3.0.0本质pypdf==3.1.0上是相同的,但是 pypdf 中的开发仍在继续
  • Borb - 活跃。

pdfminer.6:

pip install pdfminer.six

import pdfminer.pdfparser
import pdfminer.pdfdocument
h = open('path/to/file.pdf', 'rb')
p = pdfminer.pdfparser.PDFParser(h)
d = pdfminer.pdfparser.PDFDocument(p)
d.info[0]['Author']
Run Code Online (Sandbox Code Playgroud)

这将返回一个二进制字符串,包括不可解码的字符(如果存在)。例子:

  • b'Normal person'
  • b'\xfe\xff\x00A\x00B\x00C'(ABC)

要转换为字符串:

  • b'Normal person'.decode()产生字符串'Normal person'
  • b'\xfe\xff\x00A\x00B\x00C'.decode(encoding='utf-8', errors='ignore').replace('\x00', '')产生字符串'ABC'

pdf阅读器

pip install pdfreader

import pdfreader
h = open(r'path/to/file.pdf', 'rb')
d = pdfreader.PDFDocument(h)
d.metadata['Author']
Run Code Online (Sandbox Code Playgroud)

这将返回包含所请求信息的字符串,或包含所找到数据的十六进制表示形式的字符串。这也包括相同的不可解码字符。例子:

  • 'Normal person'
  • 'FEFF004100420043'(ABC)

然后,您首先需要检测这是否仍然是“编码的”,我认为这非常麻烦。通过调用这段丑陋的代码,可以将第二个字符串变成一个合理的字符串:

s = 'FEFF004100420043'
''.join([c for c in (chr(int(s[i:i+2], 16)) for i in range(0, len(s), 2)) if c.isascii()]).replace('\x00', '')
>>> 'ABC'
Run Code Online (Sandbox Code Playgroud)

博尔布

pip install borb

import borb.pdf.pdf
h = open(r'path/to/file.pdf', 'rb')
d = borb.pdf.document.Document = borb.pdf.pdf.PDF.loads(h)
str(d.get_document_info().get_author())
Run Code Online (Sandbox Code Playgroud)

这将返回一个字符串 - 如果您用str. 加载相当大的 PDF 需要很长时间。我有一份 PDF,其中 borb 因 TypeError 异常而卡住了。另请参阅borb 的专用示例存储库上的示例。


Kha*_*eel 5

注意:pyPdf 主页说不再维护它.

我使用pyPdf实现了这个.请参阅下面的示例代码.

from pyPdf import PdfFileReader
pdf_toread = PdfFileReader(open("doc2.pdf", "rb"))
pdf_info = pdf_toread.getDocumentInfo()
print(str(pdf_info))
Run Code Online (Sandbox Code Playgroud)

输出:

{'/Title': u'Microsoft Word - Agnico-Eagle - Complaint (00040197-2)', '/CreationDate': u"D:20111108111228-05'00'", '/Producer': u'Acrobat Distiller 10.0.0 (Windows)', '/ModDate': u"D:20111108112409-05'00'", '/Creator': u'PScript5.dll Version 5.2.2', '/Author': u'LdelPino'}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,pyPdf在主页上标记为不再受支持. (2认同)

Rab*_*ash 5

对于 Python 3 和新的 pdfminer(pip install pdfminer3k):

import os
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfparser import PDFDocument

fp = open("foo.pdf", 'rb')
parser = PDFParser(fp)
doc = PDFDocument(parser)
parser.set_document(doc)
doc.set_parser(parser)
if len(doc.info) > 0:
    info = doc.info[0]
    print(info)
Run Code Online (Sandbox Code Playgroud)