Camelot:從pdf中提取表格數據


工做要效率,大數據時代,獲取信息也要效率,只用不斷的造輪子,才能不斷的提升效率,今天介紹一下一款能夠直接從pdf格式的文檔中提取表格中數據的工具,Camelot!!!html


1、Camelot的介紹和安裝

1. Camelot介紹

Camelot: 一個友好的PDF表格數據抽取工具python

一個python命令行工具,使任何人都能很輕鬆的從PDF文件中抽取表格數據。git

使用Camelot從PDF文檔提取數據很是簡單github

  • Camelot容許你經過調整設置項來精確控制數據的提取過程
  • 能夠根據空白和精度指標來判斷壞的表格,並丟棄,而沒必要手動檢查
  • 每個表格數據是一個panda的dataframe,從而能夠很方便的集成到ETL和數據分析工做流中
  • 能夠把數據導出爲各類不一樣的格式好比CSV、JSON、EXCEL、HTML

2. Camelot的安裝

camelot有三種安裝方式:web

  • pip 安裝
  • conda安裝
  • 源碼安裝
  1. pip 安裝

pip install camelot-py[cv]算法

  1. conda安裝

conda install -c conda-forge camelot-pysql

  1. 源碼安裝

git clone https://www.github.com/socialcopsdev/camelot
cd camelot
pip install 「.[cv]」數據庫

注意:json

若是後面導入camelot庫包的時候,出現錯誤,多是缺乏Ghostscript包,用pip 安裝便可。svg

3. 其餘

源碼參考文檔:
https://github.com/socialcopsdev/camelot
使用文檔:
https://camelot-py.readthedocs.io/en/master/

2、Camelot的使用

1. 快速入門使用

從一個pdf文件中提取出表格:

>>> import camelot
>>> tables = camelot.read_pdf('foo.pdf')
>>> tables
<TableList n=1>
>>> tables.export('foo.csv', f='csv', compress=True) # json, excel, html
>>> tables[0]
<Table shape=(7, 7)>
>>> tables[0].parsing_report
{
    'accuracy': 99.02,
    'whitespace': 12.24,
    'order': 1,
    'page': 1
}
>>> tables[0].to_csv('foo.csv') # 也能夠提取成其餘格式 to_json, to_excel, to_html
>>> tables[0].df # 獲取一個pandas DataFrame!

2. 詳細說明

上面的例子的說明:
一、建立一個表格對象

>>> tables = camelot.read_pdf('foo.pdf')
>>> tables
<TableList n=1>   # 只檢測到一個表格

默認狀況下,Camelot僅使用PDF的第一頁來提取表。要指定多個頁面,可使用pages關鍵字參數:

>>> camelot.read_pdf('your.pdf', pages='1,2,3')

也可使用命令行執行相同的操做

camelot --pages 1,2,3 lattice your.pdf

該pages關鍵字參數接受頁面頁碼的逗號分隔的字符串。還能夠指定頁面範圍 - 例如,pages=1,4-10,20-30或pages=1,4-10,20-end。

注意:

若是pdf文件是加密的表格,須要加入password參數,值爲解密密碼

>>> tables = camelot.read_pdf('foo.pdf', password='userpass')
>>>tables
<TableList n=1>

命令行:

camelot --password userpass lattice foo.pdf

目前,Camelot僅支持使用ASCII密碼和算法代碼1或2加密的PDF 。若是沒法讀取PDF,則拋出異常。這多是因爲未提供密碼,密碼不正確或加密算法不受支持。


二、查看錶的形狀(行和列),經過表格索引查看
咱們可使用其索引訪問每一個表。從上面的代碼片斷中,咱們能夠看到該tables對象只有一個表,由於n=1。讓咱們使用索引訪問該表0並查看它shape。

>>> tables[0]
<Table shape=(7, 7)>

三、打印解析報告。

>>> print tables[0].parsing_report
{
    'accuracy': 99.02,
    'whitespace': 12.24,
    'order': 1,
    'page': 1
}

從解析的參數的評價標準能夠得出,其準確性是很好的,空白較少,這意味着表格最有可能被正確提取。可使用table對象的df屬性將表做爲pandas DataFrame訪問。


四、打印出提取表格中的內容
數據格式是pandas DataFrane,所以用df訪問

>>> tables[0].df

在這裏插入圖片描述


五、導出表格中的內容
可使用其to_csv()方法將表導出爲CSV文件。或者可使用to_json(),或方法表分別導出爲JSON格式,Excel,HTML文件或SQLite數據庫。方法以下:

  • to_csv()
  • to_json()
  • to_excel()
  • to_html()
  • to_sqlite()
>>> tables[0].to_csv('foo.csv')

上面的1~5 步驟均可以經過命令行直接完成。

camelot --format csv --output foo.csv lattice foo.pdf

使用的pdf例子的傳送門:–>here

3. camelot兩種表格解析(提取)方法

一、流解析(stream)

Stream可用於解析在單元格之間具備空格的表,以模擬表結構。它創建在PDFMiner的功能之上,即便用邊距將頁面上的字符分組爲單詞和句子。

  1. PDF頁面上的單詞根據其y軸重疊分組爲文本行。
  2. 計算文本,而後用於猜想PDF頁面上有趣的表區域。您能夠閱讀Anssi Nurminen的碩士論文,以瞭解有關此表檢測技術的更多信息。[見第20,35和40頁]
  3. 而後猜想每一個表區域內的列數。這是經過計算每一個文本行中的單詞數模式來完成的。基於此模式,選擇每一個文本行中的單詞以計算列x範圍的列表。
  4. 而後使用位於當前列x範圍內/外的單詞來擴展當前列列表。
  5. 最後,使用文本行的y範圍和列x範圍造成表格,而且頁面上找到的單詞基於其x和y座標分配給表格的單元格。

二、格子解析(lattice)

格子本質上更具備肯定性,而且它不依賴於猜想。它可用於解析在單元格之間劃分了行的表,而且它能夠自動解析頁面上存在的多個表。

它首先使用ghostscriptPDF頁面轉換爲圖像,而後經過使用OpenCV應用一組形態變換(侵蝕和膨脹)來處理它以得到水平和垂直線段

下面介紹處理的步驟:
一、檢測分割線段
在這裏插入圖片描述

二、經過重疊檢測到的線段併疊加"和"它們像素強度來檢測線的交叉點
在這裏插入圖片描述
三、經過再次重疊檢測到的線段來計算表邊界,此次是「或」它們的像素強度。
在這裏插入圖片描述
四、因爲PDF頁面的尺寸及其圖像不一樣,所以檢測到的表格邊界,線條交叉點和線段將縮放並轉換爲PDF頁面的座標空間,並建立表格的表示。
在這裏插入圖片描述
五、使用線段和線交叉檢測生成單元。
在這裏插入圖片描述
六、最後,頁面上找到的單詞將根據其x和y座標分配給表格的單元格

3、高級使用

1. 處理背景線

1. 處理背景線

2. 可視調試

3. 指定表區域

4. 指定列表分隔符

5. 沿分隔符拆分文本

6. 標記上標和下表

7. 從文本中刪除字符

8. 改善猜想的表區域

9. 改進猜想的錶行

10. 檢測短線

11. 在生成單元格中移動文本

12. 複製跨越單元格中的文本

13. 調整佈局生成


4、命令行的使用

camelot --help 查看Camelot 參數使用:`
參數說明:

參數 完成參數 參數功能
-q –quiet TEXT 不輸出日誌和警告
-p –pages TEXT 頁數範圍,能夠用都好分割符,或者頁碼範圍,例如: 1,3,4 or 1,4-end
-pw –password TEXT 解密密碼
-o -output TEXT 輸出路徑
-f –format [csv json
-z –zip 建立
-split –split_text 跨多個單元格拆分文本。
-flag –flag_size 根據字體大小標記文本。有用的檢測超/下標。
-strip –strip_text TEXT 將字符串賦值給單元格以前,表格中的字符應該被刪除
-M –margins 字符邊緣、線邊緣、單詞邊緣

在這裏插入圖片描述


在這裏插入圖片描述 ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠