python - 如何从这个压缩的 PDF/A 中提取文本?

标签 python pdf compression text-extraction pdfa

出于机器学习目的 (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

我什至试过 pdftopng (xpdf) 之后尝试 tesseract,但没有成功
那么,有没有办法使用 Python 或第三方应用程序从 PDF 中提取纯文本?

最佳答案

如果你想解压 PDF 文件中的流,我可以推荐使用 qdpf , 但在这个文件上

 qpdf --decrypt --stream-data=uncompress document.pdf out.pdf

也没有帮助。

我不知道你为什么要努力 xpdftesseract没有成功,使用 image-magick 的 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()获得一些进步感。

关于python - 如何从这个压缩的 PDF/A 中提取文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61839856/

相关文章:

python - 如何将列表的每个元素分配给单独的变量?

python - django.db.utils.OperationalError : (1044, "Access denied for user ' someuser'@'localhost' 到数据库 '/path/to/Database"')

linux - 如何搜索多个pdf文件的内容?

ruby - 如何使用 Gnuplot 创建多页 PDF 文件?

c# - 将非常大的整数压缩成尽可能小的字符串

python - 在 Python 中查找并替换(可能)嵌套列表中的元素?

javascript - 使用Python和Flask实时更新心电图

pdf - 使用 Apache PdfBox 合并多个 PDF 并创建新的 PDF/A

mysql - 使用 mysql 在压缩期间放置什么锁

algorithm - 数据压缩 - 指数分布的机器学习