媳婦兒讓我給她找一個PDF轉word免費工具,找了半天我決定給她寫一個出來^-^
之前我媳婦兒讓我給她找一個PDF轉WORD的免費工具,在網上找了半天發現要不就是收費,要不就是轉化的格式混亂。既然網上不能找到好用的免費工具那就直接來寫一個吧。人生苦短,我用python。
萬能的python肯定應該有關於這個第三方庫,百度了一下果不其然——PDFminer3k(如果你用的是python2的話那你應該使用的是pdfminer)。
我們先上程式碼然後再分析吧。
# -*- coding:utf-8 -*-
#author:菜鳥小白的學習分享
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
def parse(DataIO, save_path):
# 用檔案物件建立一個PDF文件分析器
parser = PDFParser(DataIO)
# 建立一個PDF文件
doc = PDFDocument()
# 分析器和文件相互連線
parser.set_document(doc)
doc.set_parser(parser)
# 提供初始化密碼,沒有預設為空
doc.initialize()
# 檢查文件是否可以轉成TXT,如果不可以就忽略
if not doc.is_extractable:
raise PDFTextExtractionNotAllowed
else:
# 建立PDF資源管理器,來管理共享資源
rsrcmagr = PDFResourceManager()
# 建立一個PDF裝置物件
laparams = LAParams()
# 將資源管理器和裝置物件聚合
device = PDFPageAggregator(rsrcmagr, laparams=laparams)
# 建立一個PDF直譯器物件
interpreter = PDFPageInterpreter(rsrcmagr, device)
# 迴圈遍歷列表,每次處理一個page內容
# doc.get_pages()獲取page列表
for page in doc.get_pages():
interpreter.process_page(page)
# 接收該頁面的LTPage物件
layout = device.get_result()
# 這裡的layout是一個LTPage物件 裡面存放著page解析出來的各種物件
# 一般包括LTTextBox,LTFigure,LTImage,LTTextBoxHorizontal等等一些對像
# 想要獲取文字就得獲取物件的text屬性
for x in layout:
try:
if (isinstance(x, LTTextBoxHorizontal)):
with open('%s' % (save_path), 'a') as f:
result = x.get_text()
print(result)
f.write(result + "\n")
except:
print("Failed")
if __name__ == '__main__':
#解析同一資料夾下的PDF檔案,儲存到本地doc檔案中
with open(r'菜鳥小白.pdf', 'rb') as pdf_html:
parse(pdf_html,r'11.doc')
分析過程
PDF沒有WORD、Excel這樣簡單,可以直接去讀取內容,讀取PDF檔案需要用程式以二進位制的方式讀取,然後轉化成文字。而我們通過pdfminer的轉化過程就好比是讀取出來具體內容後猜測他們的佈局,用於重建文字的結構,但是這個也無法保證100%能夠工作。
程式碼中pdfminer呼叫的每個函式作用分別為:
-
DFParser(文件分析器)
-
PDFDocument(文件物件)
-
PDFResourceManager(資源管理器)
-
PDFPageInterpreter(直譯器)
-
PDFPageAggregator(聚合器)
-
LAParams(引數分析器)
首先我們需要新建一個文件分析器和PDF文件,並且將PDF文件物件和文件分析器關聯起來。
# 用檔案物件建立一個PDF文件分析器
parser = PDFParser(DataIO)
# 建立一個PDF文件
doc = PDFDocument()
# 分析器和文件相互連線
parser.set_document(doc)
doc.set_parser(parser)
然後我們新建一個資源管理器和新建一個PDF引數物件
# 建立PDF資源管理器,來管理共享資源
rsrcmagr = PDFResourceManager()
# 建立一個PDF裝置物件
laparams = LAParams()
然後我們新建一個聚合器,用於接收資源管理器和引數物件;建立一個直譯器,接收資源管理器和聚合器。
# 將資源管理器和裝置物件聚合
device = PDFPageAggregator(rsrcmagr, laparams=laparams)
# 建立一個PDF直譯器物件
interpreter = PDFPageInterpreter(rsrcmagr, device)
然後使用get_pages()去獲取所有的頁面,用一個for迴圈遍歷每一個頁面,使用interperter頁面直譯器對頁面進行逐一聚合,然後呼叫聚合器的get_result()獲取到layout,layout中的每一個內容,只有文字內容才會被提取出來。
# 迴圈遍歷列表,每次處理一個page內容
# doc.get_pages()獲取page列表
for page in doc.get_pages():
interpreter.process_page(page)
# 接收該頁面的LTPage物件
layout = device.get_result()
# 這裡的layout是一個LTPage物件 裡面存放著page解析出來的各種物件
# 一般包括LTTextBox,LTFigure,LTImage,LTTextBoxHorizontal等等一些對像
# 想要獲取文字就得獲取物件的text屬性
for x in layout:
try:
if (isinstance(x, LTTextBoxHorizontal)):
with open('%s' % (save_path), 'a') as f:
result = x.get_text()
print(result)
f.write(result + "\n")
except:
print("Failed")
最新實現效果
原始的PDF文件
轉化後的word文件
缺陷
當前的程式碼僅能實現文字的提取,無法提取圖片。後面我們再看看能否將圖片也一起提取出來,有厲害的小夥伴也可以私信我。
最後我把這個從程式打包成了一個exe檔案,只需要將你想要轉化的PDF文件和exe檔案放在同一個資料夾內就可以雙擊執行轉化了。有需要的小夥伴可以私信菜鳥小白"PDFtoWORD"獲取下載連結。