本文已參與「新人創作禮」活動,一起開啟掘金創作之路。
工作要效率,大資料時代,獲取資訊也要效率,只用不斷的造輪子,才能不斷的提高效率,今天介紹一下一款可以直接從pdf格式的文件中提取表格中資料的工具,Camelot!!!
一、Camelot的介紹和安裝
1. Camelot介紹
Camelot: 一個友好的PDF表格資料抽取工具
一個python命令列工具,使任何人都能很輕鬆的從PDF檔案中抽取表格資料。
使用Camelot從PDF文件提取資料非常簡單
- Camelot允許你通過調整設定項來精確控制資料的提取過程
- 可以根據空白和精度指標來判斷壞的表格,並丟棄,而不必手動檢查
- 每一個表格資料是一個panda的dataframe,從而可以很方便的整合到ETL和資料分析工作流中
- 可以把資料
匯出
為各種不同的格式比如CSV、JSON、EXCEL、HTML
2. Camelot的安裝
camelot有三種安裝方式:
* pip 安裝
* conda安裝
* 原始碼安裝
- pip 安裝
pip install camelot-py[cv]
- conda安裝
conda install -c conda-forge camelot-py
- 原始碼安裝
git clone https://www.github.com/socialcopsdev/camelot
cd camelot
pip install ".[cv]"
注意:
如果後面匯入camelot庫包的時候,出現錯誤,可能是缺少Ghostscript
包,用pip 安裝即可。
3. 其他
原始碼參考文件:
https://github.com/socialcopsdev/camelot
使用文件:
https://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
```

***
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](https://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、檢測分割線段

2、通過`重疊檢測`到的線段併疊加"和"它們畫素強度來檢測線的`交叉點`。

3、通過再次`重疊檢測`到的線段來計算`表邊界`,這次是“或”它們的畫素強度。

4、由於PDF頁面的尺寸及其影象不同,因此檢測到的表格邊界,線條交叉點和線段將縮放並轉換為PDF頁面的座標空間,並建立表格的表示。

5、使用線段和線交叉檢測生成單元。

6、最後,頁面上找到的單詞將根據其x和y座標分配給表格的單元格
# 三、高階使用
## 1. 處理背景線
## 1. 處理背景線
## 2. 可視除錯
## 3. 指定表區域
## 4. 指定列表分隔符
## 5. 沿分隔符拆分文字
## 6. 標記上標和下表
## 7. 從文字中刪除字元
## 8. 改善猜測的表區域
## 9. 改進猜測的錶行
## 10. 檢測短線
## 11. 在生成單元格中移動文字
## 12. 複製跨越單元格中的文字
## 13. 調整佈局生成
***
# 四、命令列的使用
用 `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|excel|html|sqlite] | 輸出格式
-z | --zip | 建立
-split | --split_text | 跨多個單元格拆分文字。
-flag | --flag_size | 根據字型大小標記文字。有用的檢測超/下標。
-strip | --strip_text TEXT | 將字串賦值給單元格之前,表格中的字元應該被刪除
-M | --margins |
字元邊緣、線邊緣、單詞邊緣