出于机器学习目的(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 源上使用"流",就像这个一样。
结果是这样的:
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 + 正则表达式:
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'rn')
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
我什至尝试了pdftopng(xpdf(来尝试tesseract,但没有成功 那么,有没有办法使用 Python 或第三方应用程序从 PDF 中提取纯文本?
如果您想解压缩PDF文件中的流,我可以建议使用qdpf
,但是在此文件上
qpdf --decrypt --stream-data=uncompress document.pdf out.pdf
也无济于事。
我不确定为什么你对xpdf
和tesseract
的努力没有成功,使用图像魔术的convert
要在临时目录中创建PNG文件并tesseract
,您可以执行以下操作:
import os
from pathlib import Path
from tempfile import TemporaryDirectory
import subprocess
DPI=600
def call(*args):
cmd = [str(x) for x in args]
return subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode('utf-8')
def ocr(docpath, lang):
result = []
abs_path = Path(docpath).expanduser().resolve()
old_dir = os.getcwd()
out = Path('out.txt')
with TemporaryDirectory() as tmpdir:
os.chdir(tmpdir)
call('convert', '-density', DPI, abs_path, 'out.png')
index = -1
while True:
# names have no leading zeros on the digits, would be difficult to sort glob() output
# so just count them
index += 1
png = Path(f'out-{index}.png')
if not png.exists():
break
call('tesseract', '--dpi', DPI, png, out.stem, '-l', lang)
result.append(out.read_text())
os.chdir(old_dir)
return result
pages = ocr('~/Downloads/document.pdf', 'por')
print('n'.join(pages[1].splitlines()[21:24]))
这给了:
DA NÃO REALIZAÇÃO DE AUDIÊNCIA DE AUTOCOMPOSIÇÃO NO CASO EM CONCRETO
Com vista a obter maior celeridade processual, assim como da impossibilidade de conciliação entre
如果您使用的是Windows,请确保您的PDF文件没有在不同的进程中打开(如PDF查看器(,因为Windows似乎不喜欢这样。
最终print
是有限的,因为全产量非常大。
这种转换和 OCR 需要一段时间,因此您可能需要取消注释print
call()
以获得一些进度感。
您可以使用两种相当简单的技术。
1(谷歌的"Tessaract"开源OCR(光学字符识别(。 您可以将其均匀地应用于所有PDF,尽管将所有数据转换为像素,然后在它们上工作魔法在计算上会更加昂贵。 工程师时间和 CPU 时间哪个更重要? 有一个pytesseract模块。 请注意,此工具适用于图像格式,因此您必须使用GhostScript(另一个开源项目(之类的东西将所有PDF的页面转换为图像,然后在这些图像上运行[py]tessaract。
2(pyPDF可以获取每个页面,并以编程方式提取任何文本绘制操作,按照它们被绘制到页面上的顺序。这可能与页面的逻辑阅读顺序完全不同......虽然PDF可以绘制所有"a",然后绘制所有"b"(依此类推(,但实际上用"字体a"绘制所有内容,然后用"字体b"绘制所有内容更有效。 需要注意的是,"字体 b"可能只是"字体 a"的斜体版本。 这将产生更短/更有效的绘图命令流,尽管可能不是这样做的良好业务决策。
这里的问题是,一堆随机的PDF文件可能需要您执行一些OCR。 一个组装不良的PDF(一个字体子集没有"到Unicode"数据的PDF(无法正确挖掘文本,即使它只有文本绘图操作。 "如果您不知道前五个字形是"g-l-y-p-h",那么从"字体 C"绘制字形 1 到 5 并没有多大意义,因为这是它们的使用顺序。
另一方面,如果您有自制的 PDF 或所有 pdf 都来自某个已知来源(例如 Word 的 pdf 转换器(,您将提前知道会发生什么。
请注意,上面提到的我实际使用的唯一内容是Ghostscript。 我记得它有一个可靠的命令行界面,我们多年前用来为一些在线 PDF 查看器生成图像。