python實戰-pdf檔案轉txt之類的文字可編輯型別檔案
背景:最近剛好需要將一個pdf的內容打出來,這是個比較枯燥的內容,而且pdf裡面的文字明顯是規範的,所以想寫個指令碼讀取內容,直接複製貼上。剛好,python的理念就是不重複造輪子,這樣的包自然是有的,這個指令碼最主要的包就是pdfminer3k。
1.思路
解析出文件,按頁儲存進txt檔案即可。
2.完整程式碼
from pdfminer.converter import PDFPageAggregator from pdfminer.layout import LTTextBoxHorizontal, LAParams from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.pdfinterp import PDFTextExtractionNotAllowed from pdfminer.pdfparser import PDFParser, PDFDocument def parse_pdf(filepath): # 建立檔案流 fp = open(filepath, 'rb') # 從檔案中獲取資料,得到一個解析物件 parser = PDFParser(fp) # 連線文件和分析器 pdoc = PDFDocument() parser.set_document(pdoc) pdoc.set_parser(parser) # 沒有密碼,初始化密碼為空 pdoc.initialize() # 檢測文件是否提供文字提取 if not pdoc.is_extractable: raise PDFTextExtractionNotAllowed else: # 建立PDf資源管理器物件來管理共享資源,catching=False表示不快取 pm = PDFResourceManager(caching=False) # 建立一個PDF引數分析器 laparams = LAParams() # 建立頁面聚合物件 device = PDFPageAggregator(pm, laparams=laparams) # 建立一個PDF解析器物件 interpreter = PDFPageInterpreter(pm, device) # 獲取page列表 pages = pdoc.get_pages() # 迴圈遍歷page列表,按頁處理 for page in pages: # 使用頁面直譯器來讀取 interpreter.process_page(page) # 使用聚合器獲取內容 layout = device.get_result() # 這裡layout是一個LTPage物件 裡面存放著解析出的各種物件 for item in layout: # 獲取文字 if isinstance(item, LTTextBoxHorizontal): rst = item.get_text() with open("test.txt", 'a', encoding='utf-8') as f: f.write(rst) if __name__ == '__main__': filepath = 'test.pdf' parse_pdf(filepath)
3.錯誤可能
我在寫指令碼時遇到了一個問題,這個問題還比較常見。
pdfminer.pdfparser.PDFEncryptionError: Unknown algorithm: param={'CF': {'StdCF': {'AuthEvent': /DocOpen, 'CFM': /V2, 'Length':16}},'Filter':/Standard,'Length':128,'O':b':\r\x18\xf4\xe7i\x1ca\x80\xc9UqX\xdb\xdf\xa4\xaa\x0e\x80J,Xqra\xac\xe8\r\xf1\xb94\xf5','P':-3392,'R':4,'StmF':/StdCF,'StrF':/StdCF,'U':b'\xbc7/j\xc4\xc2)\xe6g\xebX\xc2\x81\x10n\x97\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'V': 4}
這段錯誤的原因主要是預設現在的pdf檔案就算你開啟就能看,但是其實還是設定了一個空密碼,而pdfminer3k是不認的,它認為就算需要密碼,這裡可以隨便找個線上網站處理一下空密碼解鎖pdf檔案。
其實這樣的空密碼加密表面上對讀者沒有影響,但是其實是為了防止複製貼上而已。
4.原始檔
5. 執行結果