簡體   English   中英

如何從這個壓縮的 PDF/A 中提取文本?

[英]How extract text from this compressed PDF/A?

出於機器學習目的 ( 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 + 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在臨時目錄和tesseract中創建 PNG 文件,您可以這樣做:

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

If you are on Windows, make sure your PDF file is not open in a different process (like a PDF viewer), as Windows doesn't seem to like that.

由於完整的 output 相當大,因此最終print數量有限。

這種轉換和 OCR-ing 需要一段時間,因此您可能需要取消對call()中的print的注釋以獲得一些進展感。

您可以使用兩種相當簡單的技術。

1)谷歌的“Tessaract”開源OCR(光學字符識別)。 您可以將其均勻地應用於所有 PDF,盡管將所有數據轉換為像素,然后對它們進行魔術處理會在計算上更加昂貴。 哪個更重要,工程師時間還是 CPU 時間? 有一個pytesseract模塊。 請注意,此工具適用於圖像格式,因此您必須使用 GhostScript(另一個開源項目)之類的工具將所有 PDF 頁面轉換為圖像,然后在這些圖像上運行 [py]tessaract。

2) pyPDF可以獲取每個頁面並以編程方式按照它們被繪制到頁面上的順序提取任何文本繪制操作。 這可能與頁面的邏輯閱讀順序完全不同......雖然 PDF可以繪制所有的 'a',然后是所有的 'b'(等等),但實際上以“字體 a”繪制所有內容更有效,然后“字體 b”中的所有內容。 需要注意的是,“font b”可能只是“font a”的斜體版本。 這會產生更短/更高效的繪圖命令 stream,盡管數量可能不是一個好的商業決策。

這里的關鍵是隨機一堆 PDF 文件可能需要你做一些 OCR。 一個組裝不良的 PDF(一個字體子集沒有“to unicode”數據)即使只有文本繪圖操作,也無法正確挖掘文本。 “如果您不知道前五個字形是“字形”,那么從“字體 C”繪制第 1 到第 5 個字形並沒有多大意義,因為那是它們的使用順序。

另一方面,如果您有自制的 PDF 或所有 pdf 都來自某個已知來源(例如 Word 的 pdf 轉換器),您將提前知道會發生什么。

請注意,上面提到的唯一我實際使用過的是 Ghostscript。 我記得它有一個可靠的命令行界面,我們用來為許多年前的一些在線 PDF 查看器生成圖像。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM