使用mupdf處理PDF中的文字
如何提取所有文檔文本
該腳本將采用文檔文件名并從其所有文本生成一個(gè)文本文件。
文檔可以是任何受支持的類(lèi)型,如 PDF、XPS 等。
該腳本作為命令行工具工作,需要將文檔文件名作為參數(shù)提供。它在腳本目錄中生成一個(gè)名為“filename.txt”的文本文件。頁(yè)面文本由換頁(yè)符分隔:
輸出將是文檔中編碼的純文本。沒(méi)有任何方式美化。特別是對(duì)于 PDF,這可能意味著輸出不符合通常的閱讀順序、意外的換行符等。
您有多種選擇來(lái)糾正此問(wèn)題 - 其中包括:
提取 HTML 格式的文本并將其存儲(chǔ)為 HTML 文檔,以便可以在任何瀏覽器中查看。
通過(guò)Page.get_text(“blocks”)將文本提取為文本塊列表。該列表的每一項(xiàng)都包含其文本的位置信息,可用于建立方便的閱讀順序。
通過(guò)Page.get_text(“words”)提取單個(gè)單詞的列表。它的項(xiàng)目是帶有位置信息的單詞。使用它來(lái)確定給定矩形中包含的文本——請(qǐng)參閱下一節(jié)。
如何從頁(yè)面中提取鍵值對(duì)
如果頁(yè)面布局在某種意義上是“可預(yù)測(cè)的” ,那么有一種簡(jiǎn)單的方法可以快速輕松地找到一組給定關(guān)鍵字的值——無(wú)需使用正則表達(dá)式。
在這種情況下,“可預(yù)測(cè)”是指:
每個(gè)關(guān)鍵字后面都有它的值——它們之間沒(méi)有其他文本。
值邊界框的底部不在關(guān)鍵字之一之上。
沒(méi)有其他限制:頁(yè)面布局可以固定也可以不固定,文本也可以存儲(chǔ)為一個(gè)字符串。鍵和值之間可以有任何距離。
如何以自然閱讀順序提取文本
PDF 文本提取的一個(gè)常見(jiàn)問(wèn)題是,文本可能不會(huì)以任何特定的閱讀順序出現(xiàn)。
這是 PDF 創(chuàng)建者(軟件或人)的責(zé)任。例如,頁(yè)眉可能是在單獨(dú)的步驟中插入的——在文檔生成之后。在這種情況下,頁(yè)眉文本將出現(xiàn)在頁(yè)面文本提取的末尾(盡管它會(huì)被 PDF 查看器軟件正確顯示)。例如,以下代碼片段將向現(xiàn)有 PDF 添加一些頁(yè)眉和頁(yè)腳行:
從以這種方式修改的頁(yè)面中提取的文本序列:原文、標(biāo)題行、頁(yè)腳行
PyMuPDF 有幾種方法可以重新建立一些閱讀順序,甚至可以重新生成接近原始的布局:
使用
sort
參數(shù)Page.get_text()
.?它將輸出從左上角到右下角排序(對(duì)于 XHTML、HTML 和 XML 輸出忽略)。fitz
在 CLI: 中使用該模塊,它會(huì)生成一個(gè)文本文件,其中的文本以保留布局的模式重新排列。許多選項(xiàng)可用于控制輸出。python?-m?fitz?gettext?...
如何從文檔中提取表格內(nèi)容
如果您在文檔中看到一個(gè)表格,您通常不會(huì)看到類(lèi)似嵌入式 Excel 或其他可識(shí)別對(duì)象的東西。它通常只是文本,經(jīng)過(guò)格式化以適當(dāng)顯示。
因此,從這樣的頁(yè)面區(qū)域中提取表格數(shù)據(jù)意味著您必須找到一種方法來(lái)(1)以圖形方式指示表格和列的邊框,以及(2)然后根據(jù)此信息提取文本。
wxPython GUI 腳本extract.py努力做到這一點(diǎn)。您可能想看一下并根據(jù)自己的喜好進(jìn)行調(diào)整。
如何標(biāo)記提取的文本
有一個(gè)標(biāo)準(zhǔn)的搜索功能可以搜索頁(yè)面上的任意文本:Page.search_for()
。它返回圍繞找到的事件的Rect對(duì)象列表。例如,這些矩形可用于自動(dòng)插入明顯標(biāo)記找到的文本的注釋。
這種方法有優(yōu)點(diǎn)也有缺點(diǎn)。優(yōu)點(diǎn)是:
搜索字符串可以包含空格并換行
大寫(xiě)或小寫(xiě)字符被同等對(duì)待
檢測(cè)并解決行尾的單詞斷字
Return 也可以是Quad對(duì)象的列表,以精確定位不平行于任一軸的文本——當(dāng)頁(yè)面旋轉(zhuǎn)不為零時(shí),也建議使用Quad輸出。
但您還有其他選擇:
此腳本用于Page.get_text("words")
查找通過(guò) cli 參數(shù)提交的字符串。此方法使用空格和換行符作為分隔符將頁(yè)面的文本分隔為“單詞”。進(jìn)一步說(shuō)明:
如果找到,則包含該字符串的完整單詞會(huì)被標(biāo)記(加下劃線)——而不僅僅是搜索字符串。
搜索字符串不能包含空格或其他空格。
如此處所示,尊重大寫(xiě)/小寫(xiě)。但這可以通過(guò)在函數(shù)mark_word中使用字符串方法lower()(甚至正則表達(dá)式)來(lái)改變。
沒(méi)有上限:所有的事件都會(huì)被檢測(cè)到。
您可以使用任何東西來(lái)標(biāo)記單詞:'Underline'、'Highlight'、'StrikeThrough' 或 'Square' 注釋等。
這是本手冊(cè)頁(yè)面的示例片段,其中“MuPDF”已用作搜索字符串。請(qǐng)注意,所有包含“MuPDF”的字符串都帶有下劃線(不僅僅是搜索字符串)。

如何標(biāo)記搜索到的文本
搜索文本并對(duì)其進(jìn)行標(biāo)記:
如何標(biāo)記非水平文本
使用“dict”/“rawdict”選項(xiàng)的文本提取Page.get_text()
也可能返回與 x 軸成非零角度的文本。這由線字典的鍵的值表示:它是那個(gè)角度的"dir"
元組。如果,則其所有跨度的文本旋轉(zhuǎn)(相同)角度 != 0。(cosine,?sine)
line["dir"]?!=?(1,?0)
然而,該方法返回的“bboxes”只是矩形——不是四邊形。因此,要正確標(biāo)記跨度文本,必須從行和跨度字典中包含的數(shù)據(jù)中恢復(fù)其四邊形。使用以下實(shí)用程序函數(shù)(v1.18.9 中的新功能)執(zhí)行此操作:
如果要一次性標(biāo)記完整行或其跨度的子集,請(qǐng)使用以下代碼段
上面的參數(shù)spans
可以指定 的任何子列表line["spans"]
。在上面的示例中,標(biāo)記了倒數(shù)第二個(gè)跨度。如果省略,則采用完整的行。
如何分析字體特征
要分析 PDF 中文本的特征,請(qǐng)使用此基本腳本作為起點(diǎn):
如何插入文本
PyMuPDF 提供了在新的或現(xiàn)有的 PDF 頁(yè)面上插入文本的方法,具有以下功能:
選擇字體,包括內(nèi)置字體和作為文件提供的字體
選擇文本特征,如粗體、斜體、字體大小、字體顏色等。
以多種方式定位文本:
作為從某一點(diǎn)開(kāi)始的簡(jiǎn)單的面向行的輸出,
或在以矩形形式提供的框中放置文本,在這種情況下也可以選擇文本對(duì)齊方式,
選擇文本是否應(yīng)置于前景(覆蓋現(xiàn)有內(nèi)容),
所有文本都可以任意“變形”,即可以通過(guò)Matrix更改其外觀,以實(shí)現(xiàn)縮放、剪切或鏡像等效果,
獨(dú)立于變形,除此之外,文本可以旋轉(zhuǎn) 90 度的整數(shù)倍
Page.insert_font()
– 為頁(yè)面安裝字體以供以后參考。結(jié)果反映在 的輸出中Document.get_page_fonts()
。字體可以是:作為文件提供,
通過(guò)字體(然后使用
Font.buffer
)已經(jīng)出現(xiàn)在這個(gè)或另一個(gè)PDF 中的某處,或者
成為內(nèi)置字體。
Page.insert_text()
– 寫(xiě)幾行文字。在內(nèi)部,這使用Shape.insert_text()
.Page.insert_textbox()
– 使文本適合給定的矩形。您可以在此處選擇文本對(duì)齊功能(左對(duì)齊、右對(duì)齊、居中對(duì)齊、兩端對(duì)齊),并控制文本是否真正適合。在內(nèi)部,這使用Shape.insert_textbox()
.
兩種文本插入方法都會(huì)根據(jù)需要自動(dòng)安裝字體。
如何編寫(xiě)文本行
在頁(yè)面上輸出一些文本行:
使用這種方法,只會(huì)控制行數(shù)不超過(guò)頁(yè)面高度。多余的行不會(huì)寫(xiě)入,返回實(shí)際行數(shù)。該計(jì)算使用根據(jù)字體大小計(jì)算的行高和 36 點(diǎn)(0.5 英寸)作為下邊距。
忽略線寬。一條線的多余部分將完全不可見(jiàn)。
但是,對(duì)于內(nèi)置字體,有一些方法可以預(yù)先計(jì)算線寬 - 請(qǐng)參閱get_text_length()
。
這是另一個(gè)例子。它使用四種不同的旋轉(zhuǎn)選項(xiàng)插入 4 個(gè)文本字符串,從而解釋了必須如何選擇文本插入點(diǎn)才能獲得所需的結(jié)果:
如何填充文本框
此腳本用文本填充 4 個(gè)不同的矩形,每次選擇不同的旋轉(zhuǎn)值:
上面使用了幾個(gè)默認(rèn)值:字體“Helvetica”、字體大小 11 和文本對(duì)齊“左”。結(jié)果將如下所示:

如何使用非標(biāo)準(zhǔn)編碼
從 v1.14 開(kāi)始,MuPDF 允許Base14_Fonts
.?在 PyMuPDF 中,這是通過(guò)一個(gè)額外的編碼參數(shù)來(lái)支持的。實(shí)際上,這僅與 Helvetica、Times-Roman 和 Courier(及其粗體/斜體形式)和 ASCII 代碼范圍之外的字符相關(guān)。在其他地方,參數(shù)被忽略。以下是如何使用標(biāo)準(zhǔn)字體 Helvetica 請(qǐng)求俄語(yǔ)編碼:
有效的編碼值為 TEXT_ENCODING_LATIN (0)、TEXT_ENCODING_GREEK (1) 和 TEXT_ENCODING_CYRILLIC(2,俄語(yǔ)),拉丁語(yǔ)為默認(rèn)值。編碼可以由所有相關(guān)的字體和文本插入方法指定。
通過(guò)上面的語(yǔ)句,字體名稱(chēng)helv自動(dòng)連接到 Helvetica 的俄語(yǔ)字體變體。使用此字體名稱(chēng)的任何后續(xù)文本插入都將使用俄語(yǔ) Helvetica 編碼。
如果稍微更改字體名稱(chēng),您還可以在同一頁(yè)面上為相同的基本字體實(shí)現(xiàn)編碼“混合” :
上面的代碼片段確實(shí)導(dǎo)致了 PDF 中 Helvetica 字體的三個(gè)不同副本。通過(guò)使用保留字“helv”的正確大小寫(xiě)拼寫(xiě)來(lái)唯一標(biāo)識(shí)(和引用)每個(gè)副本: