您可以像這樣從 PDF 中提取文本:
from PyPDF2 import PdfReader
reader = PdfReader("example.pdf")
page = reader.pages[0]
print(page.extract_text())
您還可以選擇限制要提取的文本方向,例如:
# extract only text oriented up
print(page.extract_text(0))
# extract text oriented up and turned left
print(page.extract_text((0, 90)))
Using a visitor(使用訪客)
您可以使用訪問者功能來(lái)控制要處理和提取頁(yè)面的哪一部分。您提供的訪問者函數(shù)將為每個(gè)運(yùn)算符或每個(gè)文本片段調(diào)用。
在函數(shù) extract_text 的參數(shù) visitor_text 中提供的函數(shù)有五個(gè)參數(shù):當(dāng)前轉(zhuǎn)換矩陣、文本矩陣、字體字典和字體大小。在大多數(shù)情況下,當(dāng)前位置的 x 和 y 坐標(biāo)位于當(dāng)前變換矩陣的索引 4 和 5 中。
在未知字體的情況下,字體字典可能是無(wú)。如果不是 None 它可能例如包含鍵“/BaseFont”和值“/Arial,Bold”。
警告:在復(fù)雜的文檔中,計(jì)算出的位置可能是錯(cuò)誤的。
參數(shù) visitor_operand_before 中提供的函數(shù)有四個(gè)參數(shù):操作數(shù)、操作數(shù)參數(shù)、當(dāng)前轉(zhuǎn)換矩陣和文本矩陣。
示例 2:將矩形和文本提取到 SVG 文件中
以下示例將此 PDF 文檔的第 3 頁(yè)轉(zhuǎn)換為 SVG 文件。
這樣的 SVG 導(dǎo)出可能有助于理解頁(yè)面中發(fā)生的事情。
from PyPDF2 import PdfReader
import svgwrite
reader = PdfReader("GeoBase_NHNC1_Data_Model_UML_EN.pdf")
page = reader.pages[2]
dwg = svgwrite.Drawing("GeoBase_test.svg", profile="tiny")
def visitor_svg_rect(op, args, cm, tm):
if op == b"re":
(x, y, w, h) = (args[i].as_numeric() for i in range(4))
dwg.add(dwg.rect((x, y), (w, h), stroke="red", fill_opacity=0.05))
def visitor_svg_text(text, cm, tm, fontDict, fontSize):
(x, y) = (tm[4], tm[5])
dwg.add(dwg.text(text, insert=(x, y), fill="blue"))
page.extract_text(
visitor_operand_before=visitor_svg_rect, visitor_text=visitor_svg_text
)
dwg.save()
這里生成的SVG是自下而上的,因?yàn)镻DF和SVG的坐標(biāo)系不同。
不幸的是,在復(fù)雜的 PDF 文檔中,提供給訪問者功能的坐標(biāo)可能是錯(cuò)誤的。
為什么文本提取很難
從 PDF 中提取文本可能非常棘手。在某些情況下,沒有明確的答案預(yù)期結(jié)果應(yīng)該是什么樣子:
Paragraphs: 一個(gè)段落的文本是否應(yīng)該在原始 PDF 的相同位置有換行符,或者它應(yīng)該是一個(gè)文本塊?
Page numbers: 它們應(yīng)該包含在摘錄中嗎?
Headers and Footers: 類似于頁(yè)碼 - 是否應(yīng)該提取它們?
Outlines: 是否應(yīng)該提取輪廓?
Formatting: 如果文本是粗體或斜體,它應(yīng)該包含在輸出中嗎?
Tables: 文本提取是否應(yīng)該跳過表格?它應(yīng)該只提取文本嗎?邊框是否應(yīng)該以某種類似 Markdown 的方式顯示,或者結(jié)構(gòu)是否應(yīng)該存在,例如作為 HTML 表格?你將如何處理合并的單元格?
Captions: 是否應(yīng)包括圖像和表格標(biāo)題?
Ligatures: Unicode 符號(hào) U+FB00 是兩個(gè)小寫字母“f”的單個(gè)符號(hào) ff。應(yīng)該將其解析為 Unicode 符號(hào)“ff”還是兩個(gè) ASCII 符號(hào)“ff”?
SVG images: 是否應(yīng)該提取文本部分?
Mathematical Formulas: 他們應(yīng)該被提取嗎?公式有索引和嵌套分?jǐn)?shù)。
Whitespace characters: 對(duì)于 3cm 的垂直空白應(yīng)該提取多少行?如果有 3cm 的水平空白,應(yīng)該提取多少個(gè)空格?你什么時(shí)候提取制表符,什么時(shí)候提取空格?
Footnotes: 提取多頁(yè)正文時(shí),腳注應(yīng)該放在哪里?
Hyperlinks and Metadata: 它應(yīng)該被提取嗎?它應(yīng)該以哪種格式放置在哪里?
Linearization: 假設(shè)您在段落之間有一個(gè)浮動(dòng)圖形。你是先完成段落還是在中間放置圖形文本?
還有一些問題,大多數(shù)人會(huì)同意正確的輸出,但 PDF 存儲(chǔ)信息的方式很難實(shí)現(xiàn):
Tables: 通常,表格只是絕對(duì)定位的文本。在最壞的情況下,任何一個(gè)字母都可以被絕對(duì)定位。這使得很難分辨列/行在哪里。
Images: 有時(shí) PDF 不包含顯示的文本,而是圖像。當(dāng)您無(wú)法復(fù)制文本時(shí),您會(huì)注意到這一點(diǎn)。然后是在背景中包含圖像和文本層的 PDF 文件。這通常發(fā)生在掃描文檔時(shí)。雖然今天的掃描軟件(OCR)已經(jīng)很不錯(cuò)了,但偶爾還是會(huì)出現(xiàn)故障。 PyPDF2 不是 OCR 軟件;它將無(wú)法檢測(cè)到這些故障。 PyPDF2 也永遠(yuǎn)無(wú)法從圖像中提取文本。
最后還有 PyPDF2 將處理的問題。如果您發(fā)現(xiàn)此類文本提取錯(cuò)誤,請(qǐng)與我們分享 PDF,以便我們進(jìn)行處理!
OCR 與文本提取
光學(xué)字符識(shí)別 (OCR) 是從圖像中提取文本的過程。執(zhí)行此操作的軟件稱為 OCR 軟件。 tesseract OCR 引擎是最廣為人知的開源 OCR 軟件。
PyPDF2 不是 OCR 軟件。
數(shù)字生成與掃描的 PDF 文件
PDF 文檔可以包含圖像和文本。 PDF 文件不以語(yǔ)義上有意義的方式存儲(chǔ)文本,而是以一種便于在屏幕上顯示或打印文本的方式。由于這個(gè)原因,從 PDF 中提取文本很困難。
如果您掃描文檔,生成的 PDF 通常會(huì)顯示掃描圖像。然后掃描儀還運(yùn)行 OCR 軟件并將識(shí)別出的文本放在圖像的背景中。掃描儀 OCR 軟件的結(jié)果可以通過 PyPDF2 提取。但是,在這種情況下,建議直接使用 OCR 軟件,因?yàn)殄e(cuò)誤會(huì)累積:OCR 軟件在識(shí)別文本方面并不完美。然后它以一種不適用于文本提取的格式存儲(chǔ)文本,PyPDF2 可能會(huì)在解析該格式時(shí)出錯(cuò)。
因此,我會(huì)區(qū)分三種類型的 PDF 文檔:
Digitally-born PDF files: 該文件是在計(jì)算機(jī)上以數(shù)字方式創(chuàng)建的。它可以包含圖像、文本、鏈接、大綱項(xiàng)目(又名書簽)、JavaScript ……如果放大很多,文本看起來(lái)仍然清晰。
Scanned PDF files: 掃描了任意數(shù)量的頁(yè)面。然后將圖像存儲(chǔ)在 PDF 文件中。因此,該文件只是這些圖像的容器。你不能復(fù)制文本,你沒有鏈接、大綱項(xiàng)目、JavaScript。
OCRed PDF files: 掃描儀運(yùn)行 OCR 軟件并將識(shí)別出的文本放在圖像的背景中。因此您可以復(fù)制文本,但它看起來(lái)仍然像掃描件。如果放大足夠大,您可以識(shí)別像素。
我們可以一直使用 OCR 嗎?
您現(xiàn)在可能想知道始終使用 OCR 軟件是否有意義。如果 PDF 文件是數(shù)字生成的,您可以將其渲染為圖像。
我建議不要那樣做。
PyPDF2 等文本提取軟件可以使用 PDF 中的更多信息,而不僅僅是圖像。它可以了解字體、編碼、典型字符距離和類似主題。
這意味著 PyPDF2 在處理容易混淆的字符(例如 ?oO0?
?)時(shí)具有明顯的優(yōu)勢(shì)。 PyPDF2 永遠(yuǎn)不會(huì)混淆字符。它只是讀取文件中的內(nèi)容。
PyPDF2 在處理稀有字符時(shí)也有優(yōu)勢(shì),例如. OCR 軟件將無(wú)法正確識(shí)別笑臉符號(hào)。
試圖阻止文本提取
如果共享 PDF 文檔的人想要阻止文本提取,有多種方法可以做到:
將 PDF 的內(nèi)容存儲(chǔ)為圖像
但是,如果人們?nèi)詰?yīng)能夠閱讀文檔,則不能完全阻止文本提取。在最壞的情況下,人們可以截屏、打印、掃描并在其上運(yùn)行 OCR。
更多建議: