我正在寻找有关如何使用Python的PDFMiner从PDF文件中提取文本的文档或示例。
看起来PDFMiner更新了他们的API,所有相关的例子都包含过时的代码(类和方法已经改变)。我找到的那些使从PDF文件中提取文本任务更容易的库正在使用旧的PDFMiner语法,所以我不确定该怎么做。
目前,我只是查看源代码来看是否能够弄清楚它。
我正在寻找有关如何使用Python的PDFMiner从PDF文件中提取文本的文档或示例。
看起来PDFMiner更新了他们的API,所有相关的例子都包含过时的代码(类和方法已经改变)。我找到的那些使从PDF文件中提取文本任务更容易的库正在使用旧的PDFMiner语法,所以我不确定该怎么做。
目前,我只是查看源代码来看是否能够弄清楚它。
这里是使用当前版本的PDFMiner(2016年9月)从PDF文件中提取文本的工作示例。
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO
def convert_pdf_to_txt(path):
rsrcmgr = PDFResourceManager()
retstr = StringIO()
codec = 'utf-8'
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
fp = open(path, 'rb')
interpreter = PDFPageInterpreter(rsrcmgr, device)
password = ""
maxpages = 0
caching = True
pagenos=set()
for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
interpreter.process_page(page)
text = retstr.getvalue()
fp.close()
device.close()
retstr.close()
return text
PDFMiner的结构最近发生了变化,因此这应该可以用于从PDF文件中提取文本。
编辑:截至2018年6月7日仍可使用。在Python 3.x版本中验证通过。
编辑:此解决方案适用于2019年10月3日的Python 3.7。我使用了Python库pdfminer.six
,该库于2018年11月发布。
import sys reload(sys) sys.setdefaultencoding('utf-8')
- sib10file(path, 'rb')
更改为open(path, 'rb')
才能让我的工作。 - craned这个在2020年5月使用Python3中的PDFminer six工具包是可行的。
$ pip install pdfminer.six
from pdfminer.high_level import extract_text
text = extract_text('report.pdf')
或者:
with open('report.pdf','rb') as f:
text = extract_text(f)
如果 PDF 已经在内存中,例如使用 requests 库从网络检索到了 PDF,可以使用 io
库将其转换为流:
import io
response = requests.get(url)
text = extract_text(io.BytesIO(response.content))
相比较PyPDF2(在处理特定类型的PDF时失败),PDFminer.six表现更加可靠,尤其是针对PDF版本1.7。
然而,PDFminer.six进行文本提取的速度比PyPDF2慢了6倍左右。
我在15寸MBP上使用timeit
计时,对10页PDF文件进行文本提取,并仅计算提取函数的时间(不包括文件打开等时间),得到以下结果:
PDFminer.six: 2.88 sec
PyPDF2: 0.45 sec
pdfminer.six需要pycryptodome支持,而pycryptodome需要GCC和其他组件的安装,这使得在Alpine Linux上,即使是最小的安装docker镜像也从80 MB增加到了350 MB。PyPDF2没有显著的存储影响。
更新(2022年8月4日):根据Martin Thoma的说法,过去两年中PyPDF2有了很大的改进,因此也可以尝试使用它。这是他的基准测试结果。
DuckPuncher提供了一个非常好的答案,对于Python3,请确保您安装了pdfminer2并执行以下操作:
import io
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
def convert_pdf_to_txt(path):
rsrcmgr = PDFResourceManager()
retstr = io.StringIO()
codec = 'utf-8'
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
fp = open(path, 'rb')
interpreter = PDFPageInterpreter(rsrcmgr, device)
password = ""
maxpages = 0
caching = True
pagenos = set()
for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages,
password=password,
caching=caching,
check_extractable=True):
interpreter.process_page(page)
fp.close()
device.close()
text = retstr.getvalue()
retstr.close()
return text
全面披露,我是pdfminer.six的维护者之一。它是Python 3版本的pdfminer社区维护版本。
现在,它有多个API可用于从PDF中提取文本,具体取决于您的需求。在幕后,所有这些API都使用相同的逻辑进行解析和分析布局。
(以下所有示例假定您的PDF文件名为example.pdf)
命令行
如果您只想提取文本一次,可以使用命令行工具pdf2txt.py:
$ pdf2txt.py example.pdf
高级 API
如果你想用 Python 提取文本(属性),你可以使用高级 API。如果你想要以编程方式从 PDF 中提取信息,这种方法是首选的解决方案。
from pdfminer.high_level import extract_text
# Extract text from a pdf.
text = extract_text('example.pdf')
# Extract iterable of LTPage objects.
pages = extract_pages('example.pdf')
可组合 API
还有一种可组合的 API,可以在处理返回的对象时提供很多灵活性。例如,它允许您创建自己的布局算法。其他答案中也建议使用这种方法,但我只建议在需要自定义某些组件时才使用。
from io import StringIO
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfparser import PDFParser
output_string = StringIO()
with open('example.pdf', 'rb') as in_file:
parser = PDFParser(in_file)
doc = PDFDocument(parser)
rsrcmgr = PDFResourceManager()
device = TextConverter(rsrcmgr, output_string, laparams=LAParams())
interpreter = PDFPageInterpreter(rsrcmgr, device)
for page in PDFPage.create_pages(doc):
interpreter.process_page(page)
print(output_string.getvalue())
类似的问题和答案在这里。我会尽力保持它们同步。
这段代码已经经过 Python 3 版本的 PDFminer (pdfminer-20191125)测试。
from pdfminer.layout import LAParams
from pdfminer.converter import PDFPageAggregator
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.layout import LTTextBoxHorizontal
def parsedocument(document):
# convert all horizontal text into a lines list (one entry per line)
# document is a file stream
lines = []
rsrcmgr = PDFResourceManager()
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
interpreter = PDFPageInterpreter(rsrcmgr, device)
for page in PDFPage.get_pages(document):
interpreter.process_page(page)
layout = device.get_result()
for element in layout:
if isinstance(element, LTTextBoxHorizontal):
lines.extend(element.get_text().splitlines())
return lines
我知道这是一个老问题。 对于任何试图使用pdfminer的人,你应该切换到pdfminer.six,它是当前维护的版本。
PDFminer
不支持Python 3.x.x。这可能是你遇到import
错误的原因。如果是这样,你应该使用pdfminer3k
,因为它是该库的Python 3导入版本。 - WGS