出于机器学习的目的(sckit-learn),我需要从许多PDF文件中提取原始文本。首先,我使用xpdf pdftotext执行此任务:
exe = r'"'+os.path.join(xpdf_path,"pdftotext.exe")+'"'
cmd = exe+" "+"\""+pdf+"\""+" "+"\""+pdf+".txt"+"\""
subprocess.check_output(cmd)
with open(pdf+".txt") as f:
texto_converted = f.read()
但是不幸的是,对于其中的少数人,我无法获得文本,因为他们在其pdf来源上使用了“流”,例如this one。
结果是这样的:
59!"#$%&'()*+,-.#/#01"21"" 345667.0*(879:4$;<;4=<6>4?$@"12!/ 21#$@A$3A$>@>BCDCEFGCHIJKIJLMNIJILOCNPQRDS QPFTRPUCTCVQWBCTTQXFPYTO"21 "#/!"#(Z[12\&A+],$3^_3;9`Z &a# .2"#.b#"(#c#A(87*95d$d4?$d3e#Z"f#\"#2b?2"#`Z 2"!eb2"#H1TBRgF JhiO
jFK# 2"k#`Z !#212##"elf/e21m#*c!n2!!#/bZ!#2#`Z "eo ]$5<$@;A533> "/\ko/f\#e#e#p
我什至尝试使用zlib + regex:
import re
import zlib
pdf = open("pdfa.pdf", "rb").read()
stream = re.compile(b'.*?FlateDecode.*?stream(.*?)endstream', re.S)
for s in re.findall(stream,pdf):
s = s.strip(b'\r\n')
try:
print(zlib.decompress(s).decode('UTF-8'))
print("")
except:
pass
结果是这样的:
1 0 -10 -10 10 10 d1
0.01 0 0 0.01 0 0 cm
1 0 -10 -10 10 10 d1
0.01 0 0 0.01 0 0 cm
所以,有没有办法像使用Python那样从PDF中提取纯文本?
您可以使用两种相当简单的技术。
1)Google的“ Tessaract”开源OCR(光学字符识别)。您可以将其均匀地应用于所有PDF,尽管将所有数据转换为像素,然后对其进行魔术处理将在计算上更加昂贵。工程师时间或CPU时间哪个更重要?有一个pytesseract模块。请注意,该工具适用于图像格式,因此您必须使用GhostScript(另一个开源项目)之类的东西将PDF的所有页面都转换为图像,然后对这些图像运行[py] tessaract。
2)pyPDF可以获取每个页面并以编程方式提取任何文本绘制操作按照它们在页面上的绘制顺序。这可能与页面的逻辑阅读顺序完全不同...当PDF could绘制所有的“ a”然后绘制所有的“ b”(依此类推)时,实际上绘制“ font”字体的效率更高a”,那么“ font b”中的所有内容。请务必注意,“字体b”可能只是“字体a”的斜体形式。这会产生更短/更有效的绘制命令流,尽管这样做的数量可能不是一个好的商业决策。
这里的缺点是,随机生成一堆PDF文件可能需要您执行一些OCR。组装不良的PDF(一个字体子集没有“要unicode”数据的)即使文本绘制操作也别无选择,也无法正确挖掘文本。 “如果您不知道前五个字形是“ g-l-y-p-h”,那么从“字体C”中绘制一到五个字形就没有多大意义,因为这是它们的使用顺序。
另一方面,如果您拥有本地生成的PDF或所有pdf都来自某个已知来源(例如Word的pdf转换器,您将事先知道会发生什么。
请注意,我实际使用的上述唯一内容就是Ghostscript。我记得它有一个可靠的命令行界面,我们用来为一些多年以前的在线PDF查看器生成图像。