Python 竟能解析 PDF 表格

需求

公司的PDF年報中有各種各樣的表格,需要對其中的某些具體的小標題下的表格解析出來,也就是所謂的數據結構化。

Python 竟能解析 PDF 表格

解決方案

通過看別人寫的博客,發現python裡面有關PDF解析的通常有以下四種:

  • pdfminer,擅長僅僅是文字的解析,本小白試過了,是把表格解析成普通的文本,還經常會伴隨一些莫名奇妙的不認識的符號。這個方案pass掉
  • pdf2html,看例是把pdf解析成html,但是html的標籤並沒有規律,解析一個還行,但是本小白是許多的pdf文檔下小標題的表格,這個方案直接pass掉
  • tabula,這個是我看過的前輩寫的博客中使用最多的,本人用過了。對於簡單的表格,也就是單元格中沒有換行的,表頭表尾形式不復雜的,這個方案的值得推薦。電腦需要有Java的環境。
  • pdfplumber,這個是看了知乎上的一個大佬的發現,並且自己安裝成功之後,發現最小眾,但是最符合我的需求的解決方案。前提是是需要安裝ImageMagick的

實施解決

本人一共使用了兩種方案解決了我的需求,分別是tabula和pdfplumber

先做前期的工作

1,將PDF文件轉化為JPG格式,進行搜索關鍵字,查看想要的表格的頁碼比如下圖中的風險管理狀況的得分表:

風險管理狀況

Python 竟能解析 PDF 表格

代碼如下:

#pdf 拆分為jpg

from pdf2image import convert_from_path,convert_from_bytes

import tempfile

import pdf2image

def pdf2image(I_path,O_path):

with tempfile.TemporaryDirectory() as path:

images_from_path = convert_from_path(I_path,output_folder=O_path,fmt='jpg')

I_path="/Users/gaohua/Desktop/33.PDF"

O_path="/Users/gaohua/Desktop/33"

pdf2image(I_path,O_path)

#文檔重命名

import os

path="/Users/gaohua/Desktop/33"

def rename_file(path):

for file in os.listdir(path):

os.rename(os.path.join(path,file),os.path.join(path,file[-5:]))

rename_file(path)

from aip import AipOcr

def baidu_aip(APP_ID,API_KEY,SECRET_KEY):

client = AipOcr(APP_ID, API_KEY, SECRET_KEY)

return(client)

APP_ID = '11659928'

API_KEY = 'Ogkg6buRucGnKtfeoamjg7rT'

SECRET_KEY = 'OlCLKVhaYMyqYwzvlaQ5uVgfUxzOlkcr'

client=baidu_aip(APP_ID,API_KEY,SECRET_KEY)

def get_file_content(path):

with open(path,'rb') as fp:

return fp.read()

def find_page(path,key_words):

for file in os.listdir(path)[1:-1]:

result = client.basicGeneral(get_file_content(os.path.join(path,file)))

for item in result["words_result"]:

# print(item["words"])#輸出解析的pdf文字

if key_words in item["words"]:

return (file.strip('.jpg'))

調用函數的輸出如下

key_words="風險管理狀況"

page=find_page(path,key_words)

print(page)

會輸出相應的頁碼

首先就是第一種方法:tabula

具體的操作方法如下:

import tabula

# Read pdf into DataFrame

df = tabula.read_pdf("/Users/gaohua/Desktop/33.pdf",pages=str(page))

df

這個直接返回的是一個數據幀,所以就直接是結構化的數據啦!

輸出結果是這樣的:

Python 竟能解析 PDF 表格

這樣的話,我們就已經完成了我們的需求啦!後續的關於寫入的Excel中中的話,在下就部多言啦!可以移步熊貓或者為pywin32哦!

雖然塔布拉是很方便,但是它的輸出是真的不方便,而且還需要裝的的的java的環境,JAVA的環境變量不好搞

有時候還會輸出亂七八糟的東西,比如有時候會輸出繁體的中文,我就遇到過...

所以保險起見

這裡再給出第二個解決方案:

再次就是二個解決方案pdfplumber

import pdfplumber

pdf = pdfplumber.open("/Users/gaohua/Desktop/33.pdf")

p0 = pdf.pages[int(page)-1]#注意此處的pages是一個列表,索引是從0開始的

table = p0.extract_table()

import pandas as pd

df = pd.DataFrame(table[1:], columns=table[0])

df

輸出如下:

Python 竟能解析 PDF 表格

雖然為了展示對比的方便,這裡都是用了同樣的一個表格,但是方案2的解決真的要比1好

別問我為啥知道2比1好,你試試用1去解析一些帶有文字格式的表格,帶有複雜的表頭的表格,你就知道啦!我在這裡並沒有在瞎說,而且還得裝的的java的,後者只裝一個的ImageMagick的就行,而且ImageMagick的很有用的

總結

本次一共總和運用了百度OCR的接口,百度AIP這個東西嘛!這簡直就是男人的寶庫!自己去看看就知道啦!

還有就是使用了PDF格式的解析的包

但是還是有不足的哦,就是這兩個解決方案都是針對於比較乖巧的表格的,就是橫線和豎線都比較完整的表格的,像下面的這種表格:

Python 竟能解析 PDF 表格


分享到:


相關文章: