Camelot:從pdf中提取表格資料

語言: CN / TW / HK

本文已參與「新人創作禮」活動,一起開啟掘金創作之路。


工作要效率,大資料時代,獲取資訊也要效率,只用不斷的造輪子,才能不斷的提高效率,今天介紹一下一款可以直接從pdf格式的文件中提取表格中資料的工具,Camelot!!!


一、Camelot的介紹和安裝

1. Camelot介紹

Camelot: 一個友好的PDF表格資料抽取工具

一個python命令列工具,使任何人都能很輕鬆的從PDF檔案中抽取表格資料。

使用Camelot從PDF文件提取資料非常簡單

  • Camelot允許你通過調整設定項來精確控制資料的提取過程
  • 可以根據空白和精度指標來判斷壞的表格,並丟棄,而不必手動檢查
  • 每一個表格資料是一個panda的dataframe,從而可以很方便的整合到ETL和資料分析工作流中
  • 可以把資料匯出為各種不同的格式比如CSV、JSON、EXCEL、HTML

2. Camelot的安裝

camelot有三種安裝方式: * pip 安裝 * conda安裝 * 原始碼安裝

  1. pip 安裝

    pip install camelot-py[cv]

  2. conda安裝

    conda install -c conda-forge camelot-py

  3. 原始碼安裝

    git clone http://www.github.com/socialcopsdev/camelot cd camelot pip install ".[cv]"

注意:

如果後面匯入camelot庫包的時候,出現錯誤,可能是缺少Ghostscript包,用pip 安裝即可。

3. 其他

原始碼參考文件: http://github.com/socialcopsdev/camelot 使用文件: http://camelot-py.readthedocs.io/en/master/

二、Camelot的使用

1. 快速入門使用

從一個pdf檔案中提取出表格:

```python

import camelot tables = camelot.read_pdf('foo.pdf') tables tables.export('foo.csv', f='csv', compress=True) # json, excel, html tables[0]

>>> 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. 詳細說明 上面的例子的說明: 1、建立一個表格物件 ```python >>> tables = camelot.read_pdf('foo.pdf') >>> tables # 只檢測到一個表格 ``` 預設情況下,Camelot僅使用PDF的`第一頁`來提取表。要指定多個頁面,可以使用pages關鍵字引數: ```python >>> camelot.read_pdf('your.pdf', pages='1,2,3') ``` 也可以使用命令列執行相同的操作 ```python camelot --pages 1,2,3 lattice your.pdf ``` 該pages關鍵字引數接受頁面頁碼的逗號分隔的字串。還可以指定頁面範圍 - 例如,pages=1,4-10,20-30或pages=1,4-10,20-end。 注意: >如果pdf檔案是加密的表格,需要加入password引數,值為解密密碼 >```python >>>> tables = camelot.read_pdf('foo.pdf', password='userpass') >>>>tables > >``` >命令列: >```python > camelot --password userpass lattice foo.pdf > ``` > 目前,Camelot僅支援使用ASCII密碼和演算法程式碼1或2加密的PDF 。如果無法讀取PDF,則丟擲異常。這可能是由於未提供密碼,密碼不正確或加密演算法不受支援。 *** 2、查看錶的形狀(行和列),通過表格索引檢視 我們可以使用其索引訪問每個表。從上面的程式碼片段中,我們可以看到該tables物件只有一個表,因為n=1。讓我們使用索引訪問該表0並檢視它shape。 ```python >>> tables[0]
``` *** 3、列印解析報告。 ```python >>> print tables[0].parsing_report { 'accuracy': 99.02, 'whitespace': 12.24, 'order': 1, 'page': 1 } ``` 從解析的引數的評價標準可以得出,其準確性是很好的,空白較少,這意味著表格最有可能被正確提取。可以使用table物件的df屬性將表作為pandas DataFrame訪問。 *** 4、打印出提取表格中的內容 資料格式是pandas DataFrane,因此用df訪問 ```python >>> tables[0].df ``` ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/098bc0dd797f46c2954b385f8df2cf01~tplv-k3u1fbpfcp-zoom-1.image) *** 5、匯出表格中的內容 可以使用其to_csv()方法將表匯出為CSV檔案。或者可以使用to_json(),或方法表分別匯出為JSON格式,Excel,HTML檔案或SQLite資料庫。方法如下: * to_csv() * to_json() * to_excel() * to_html() * to_sqlite() ```python >>> tables[0].to_csv('foo.csv') ``` *** 上面的1~5 步驟都可以通過命令列直接完成。 ```python camelot --format csv --output foo.csv lattice foo.pdf ``` 使用的pdf例子的傳送門:-->[here](http://camelot-py.readthedocs.io/en/master/_static/pdf/foo.pdf) ## 3. camelot兩種表格解析(提取)方法 ### 1、流解析(stream) Stream可用於解析在`單元格之間具有空格`的表,以模擬表結構。它建立在PDFMiner的功能之上,即使用邊距將頁面上的字元分組為單詞和句子。 1. PDF頁面上的單詞根據其y軸重疊分組為文字行。 2. 計算文字,然後用於猜測PDF頁面上有趣的表區域。您可以閱讀[Anssi Nurminen的碩士論文](http://dspace.cc.tut.fi/dpub/bitstream/handle/123456789/21520/Nurminen.pdf?sequence=3),以瞭解有關此表檢測技術的更多資訊。[見第20,35和40頁] 3. 然後猜測每個表區域內的列數。這是通過計算每個文字行中的單詞數模式來完成的。基於此模式,選擇每個文字行中的單詞以計算列x範圍的列表。 4. 然後使用位於當前列x範圍內/外的單詞來擴充套件當前列列表。 5. 最後,使用文字行的y範圍和列x範圍形成表格,並且頁面上找到的單詞基於其x和y座標分配給表格的單元格。 ### 2、格子解析(lattice) 格子本質上更具有`確定性`,並且它不依賴於猜測。它可用於解析在單元格之間劃分了行的表,並且它可以自動解析頁面上存在的多個表。 它首先使用`ghostscript`將`PDF頁面`轉換為`影象`,然後通過使用`OpenCV`應用`一組形態變換(侵蝕和膨脹)`來處理它以獲得`水平和垂直線段`。 下面介紹處理的步驟: 1、檢測分割線段 ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/171be0f6520c4ce3b8bebe73f288809a~tplv-k3u1fbpfcp-zoom-1.image) 2、通過`重疊檢測`到的線段併疊加"和"它們畫素強度來檢測線的`交叉點`。 ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a6ebf8d81f84482f859b3141a7e0fa96~tplv-k3u1fbpfcp-zoom-1.image) 3、通過再次`重疊檢測`到的線段來計算`表邊界`,這次是“或”它們的畫素強度。 ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/01c4cc1054f24d57ab1b672337f77ab5~tplv-k3u1fbpfcp-zoom-1.image) 4、由於PDF頁面的尺寸及其影象不同,因此檢測到的表格邊界,線條交叉點和線段將縮放並轉換為PDF頁面的座標空間,並建立表格的表示。 ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4d6f8d4c68704fd580326944b8f440fc~tplv-k3u1fbpfcp-zoom-1.image) 5、使用線段和線交叉檢測生成單元。 ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/144307636e674c5c827410b706d8c6d6~tplv-k3u1fbpfcp-zoom-1.image) 6、最後,頁面上找到的單詞將根據其x和y座標分配給表格的單元格 # 三、高階使用 ## 1. 處理背景線 ## 1. 處理背景線 ## 2. 可視除錯 ## 3. 指定表區域 ## 4. 指定列表分隔符 ## 5. 沿分隔符拆分文字 ## 6. 標記上標和下表 ## 7. 從文字中刪除字元 ## 8. 改善猜測的表區域 ## 9. 改進猜測的錶行 ## 10. 檢測短線 ## 11. 在生成單元格中移動文字 ## 12. 複製跨越單元格中的文字 ## 13. 調整佈局生成 *** # 四、命令列的使用 用 `camelot --help ` 檢視Camelot 引數使用:![`](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4ef2e99f7a3b4b21aa5070d8b4f6e36c~tplv-k3u1fbpfcp-zoom-1.image) 引數說明: 引數 | 完成引數 | 引數功能 :------|:----------------|:--------------- -q | --quiet TEXT | 不輸出日誌和警告 -p | --pages TEXT | 頁數範圍,可以用都好分割符,或者頁碼範圍,例如: 1,3,4 or 1,4-end -pw | --password TEXT | 解密密碼 -o | -output TEXT | 輸出路徑 -f | --format [csv|json|excel|html|sqlite] | 輸出格式 -z | --zip | 建立 -split | --split_text | 跨多個單元格拆分文字。 -flag | --flag_size | 根據字型大小標記文字。有用的檢測超/下標。 -strip | --strip_text TEXT | 將字串賦值給單元格之前,表格中的字元應該被刪除 -M | --margins | 字元邊緣、線邊緣、單詞邊緣