微吼云上線多路互動直播服務 加速多場景互動直播落地
1010
2025-04-01
PDF 文字&表格識別與轉換
相信大家和我一樣也會經常遇到如下的情況:
查找的資料是PDF格式的,無法批量處理其中的文字信息
PDF中的表格資料很難轉換為方便下一步處理的格式(csv,excel,pd.dataframe)
網上PDF轉換工具通常是收費的,使用起來有所顧慮
這里為大家介紹一種開源的解決方案,也是小編自己基于PDFminer,PyMuPDF這兩個開源項目開發的項目。首先,這兩個項目僅僅支持非掃描版的PDF文件,如果是掃描版的,屬于OCR的范疇,不在此討論。本文中一些背景和文檔的翻譯來自于自己的理解,如有不合適的地方,歡迎大家指正交流。
PDF 背景
最初的PDF(Portable Document Format) 是基于上世紀90年代很流行的PostScript page description language 開發的一種面向對象的“語言“,它提供了一種高效方便的機制使得文件在不同的硬件,操作系統,軟件查看和打印(格式和內容的穩定)時內容和格式不會發生變化。最初的PDF設計發布于1993年,如今超過它已經成為了一種廣泛的標準電子信息交換介質。
PDF基本格式
一個PDF文件包含了一系列的objects共同描述每一頁的表象(appearance),它們是由自包含的一系列字節序列來表達的(self-contained sequence of bytes)。
PDF中的每一頁都有可能由文字,圖片組成。每一頁在PDF創建時會生成一個content stream,它包含了一系列的graphics objects,而這些objects的表象(appearance)都被充分定義了。簡單的來理解就是,我們所能看到的每一個信息都是由一個或者多個objects(如描述文字的stream object, 描述圖片的image object等)來描述的。
PDFminer介紹
這個開源的項目最初是由一位日本老哥與2004年開始的,而他最近的一次更新是4個月前,雖然只是上來跟新了一下readme并聲稱“本項目不再維護了,目前正在維護并且支持python3.x的是pdfminer.six”。
那么這個GitHub 6K star的項目具體做了哪些工作呢?我最初打開GitHub看了30分鐘源碼,腦海里都是“小盆友你是否有很多問號??“。 是的,想要讀懂這個項目,你首先要對那個1300多頁的PDF reference manual有一定的了解。而這個著作我保證比這位日本老哥的10年大作更勸退。怎么辦呢,好在網絡上已經有一位高人替我們趟了坑,告訴我們這個pdfminer的項目應該怎么入手了,它的名字就是pdfminer-read the docs
""" PDF?is?evil.? PDF是魔鬼。 Although?it?is?called?a?PDF?“document”,?it’s?nothing?like?Word?or?HTML?document.? 盡管它被稱為“文件”,但是它一點不像我們所熟悉的word文檔或者HTML文檔。 PDF?is?more?like?a?graphic?representation.? 它更像一種圖形化的表達。 PDF?contents?are?just?a?bunch?of?instructions?that?tell?how?to?place?the?stuff?at?each?exact?position?on?a?display?or?paper.? PDF的內容只是一堆的指令集告訴(app或者打印機)如何去把東西(文字,圖片)準確的放在顯示屏或者紙的某個位置(坐標)上。 In?most?cases,?it?has?no?logical?structure?such?as?sentences?or?paragraphs?and?it?cannot?adapt?itself?when?the?paper?size?changes.? 很多時候,它是沒有像句子或者段落這種邏輯結構的,而且它無法自適應紙張的變化。 PDFMiner?attempts?to?reconstruct?some?of?those?structures?by?guessing?from its?positioning,?but?there’s?nothing?guaranteed?to?work.?Ugly,?I?know.?Again,?PDF?is?evil. PDFMiner嘗試依據坐標系統去重新組裝這其中的一些指令集,但是沒有什么是保證能夠工作的。。丑陋,PDF是惡魔啊~~ """
這一段其實講出了我在面對不同格式,不同APP生成的PDF時候所面臨的絕望,有時候參數的微微調整可以對使某些PDF的識別轉換率飆升,然而卻會直接導致其他的一些PDF中大量的objects丟失,只能通過不斷的調整參數達到一種合適的轉換效果。
""" Because?a?PDF?file?has?such?a?big?and?complex?structure,?parsing?a?PDF?file?as?a?whole?is?time?and?memory?consuming. 因為PDF文件有著如此巨大且復雜的結構,將一個PDF文件作為一個整體一次性解析是非常不劃算的。 However,?not?every?part?is?needed?for?most?PDF?processing?tasks.?Therefore?PDFMiner?takes?a?strategy?of?lazy?parsing,?which?is?to?parse?the?stuff?only?when?it’s?necessary.? 但是呢,由于在PDF?processing?tasks中并非每個部分都是必要的。因此,PDFMiner嘗試了一種lazy的策略,就是只在必要時解析內容(哈??)。 To?parse?PDF?files,?you?need?to?use?at?least?two?classes:PDFParser?and?PDFDocument.? 解析PDF文件,至少需要PDFParser和PDFDocument這兩個classes(好嘛,這就到class了) These?two?objects?are?associated?with?each?other.? 這兩個objects是互相聯系的(這我也猜到了)。 PDFParser?fetches?data?from?a?file,?and?PDFDocument?stores?it.? PDFParser從文件中獲取數據,PDFDocument存儲數據。(不然嘞...) You’ll?also?need?PDFPageInterpreter?to?process?the?page?contents?and PDFDevice?to?translate?it?to?whatever?you?need.? 你還需要PDFPageInterpreter去處理每頁上的內容,以及PDFDevice去把他們轉換為你需要的東西。(說好的2個classes呢) PDFResourceManager?is?used?to?store?shared?resources?such?as?fonts?or?images. PDFResourceManager用來存儲一些分享的資源,如字體和圖片。(字體資源我能理解,怎么images也是分享的呢,這里存疑哈) """
到此看上去非常明朗了, 我們來看一段示例代碼
這里給大家打個比方,PDFResourceManager是餐廳的大廚,它負責給你做飯,LAParams是用餐者的口味,咸淡啦要不要蔥花放不放醬油啦,PDFPageAggregator這個是送餐的服務員,TA把大廚給你做的飯裝在盤子里,但是呢大廚做了一百八十多道菜,總共3鍋,服務員也不好一下子給你,他就負責把一道菜(每頁的內容),按順序(aggregate)給到你吃。PDFPageInterpreter呢就是餐具了,你用它來吃(procee_page)每道菜,這個菜呢最后就是服務員送給你的東西了(layout)。由此可見日本人的餐桌文化很嚴謹,每一個步驟都得到了尊重。當然我對這如此復雜的必要性產生了懷疑,但是這個不重要哈,可能是之前所說的lazy strategy的方略所必須付出的吧。
到了這一步,你應該能對著自己的屏幕上閃現著pdf文件中的文字而歡欣鼓舞了。但是呢這個只是我們長征的第一步,至于如何將文字拼成段落,將表格轉為excel格式,提取圖片,GUI手動選擇并轉化輸出表格json,且聽下回分解。
文字識別
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。