另類爬蟲:從PDF檔案中爬取表格資料
簡介
本文將展示一個稍微不一樣點的爬蟲。
以往我們的爬蟲都是從網路上爬取資料,因為網頁一般用HTML,CSS,JavaScript程式碼寫成,因此,有大量成熟的技術來爬取網頁中的各種資料。這次,我們需要爬取的文件為PDF檔案。本文將展示如何利用Python的camelot模組從PDF檔案中爬取表格資料。
在我們的日常生活和工作中,PDF檔案無疑是最常用的檔案格式之一,小到教材、課件,大到合同、規劃書,我們都能見到這種檔案格式。但如何從PDF檔案中提取其中的表格,這卻是一個大難題。因為PDF中沒有一個內部的表示方式來表示一個表格。這使得表格資料很難被抽取出來做分析。那麼,我們如何做到從PDF中爬取表格資料呢?
答案是Python的camelot模組!
camelot是Python的一個模組,它能夠讓任何人輕鬆地從PDF檔案中提取表格資料。可以使用以下命令安裝camelot模組(安裝時間較長):
pip install camelot-py
camelot模組的官方文件地址為:https://camelot-py.readthedocs.io/en/master/。
下面將展示如何利用camelot模組從PDF檔案中爬取表格資料。
例1
首先,讓我們看一個簡單的例子:eg.pdf,整個檔案只有一頁,這一頁中只有一個表格,如下:
使用以下Python程式碼就可以提取該PDF檔案中的表格:
import camelot
# 從PDF檔案中提取表格
tables = camelot.read_pdf('E://eg.pdf', pages='1', flavor= 'stream')
# 表格資訊
print(tables)
print(tables[0])
# 表格資料
print(tables[0].data)
輸出結果為:
<TableList n=1>
<Table shape=(4, 4)>
[['ID', '姓名', '城市', '性別'], ['1', 'Alex', 'Shanghai', 'M'], ['2', 'Bob', 'Beijing', 'F'], ['3', 'Cook', 'New York', 'M']]
分析程式碼,camelot.read_pdf()為camelot的從表格中提取資料的函式,輸入的引數為PDF檔案的路徑,頁碼(pages)和表格解析方法(有stream和lattice兩個方法)。對於表格解析方法,預設的方法為lattice,而stream方法預設會把整個PDF頁面當做一個表格來解析,如果需要指定解析頁面中的區域,可以使用table_area這個引數。
camelot模組的便捷之處還在於它提供了將提取後的表格資料直接轉化為pandas,csv,JSON,html的函式,如tables[0].df,tables[0].to_csv()函式等。我們以輸出csv檔案為例:
import camelot
# 從PDF檔案中提取表格
tables = camelot.read_pdf('E://eg.pdf', pages='1', flavor='stream')
# 將表格資料轉化為csv檔案
tables[0].to_csv('E://eg.csv')
得到的csv檔案如下:
例2
在例2中,我們將提取PDF頁面中的某一區域的表格的資料。PDF檔案的頁面(部分)如下:
為了提取整個頁面中唯一的表格,我們需要定位表格所在的位置。PDF檔案的座標系統與圖片不一樣,它以左下角的頂點為原點,向右為x軸,向上為y軸,可以通過以下Python程式碼輸出整個頁面的文字的座標情況:
import camelot
# 從PDF中提取表格
tables = camelot.read_pdf('G://Statistics-Fundamentals-Succinctly.pdf', pages='53', \
flavor='stream')
# 繪製PDF文件的座標,定位表格所在的位置
tables[0].plot('text')
輸出結果為:
UserWarning: No tables found on page-53 [stream.py:292]
整個程式碼沒有找到表格,這是因為stream方法預設將整個PDF頁面當作表格,因此就沒有找到表格。但是繪製的頁面座標的影象如下:
仔細對比之前的PDF頁面,我們不難發現,表格對應的區域的左上角座標為(50,620),右下角的座標為(500,540)。我們在read_pdf()函式中加入table_area引數,完整的Python程式碼如下:
import camelot
# 識別指定區域中的表格資料
tables = camelot.read_pdf('G://Statistics-Fundamentals-Succinctly.pdf', pages='53', \
flavor='stream', table_area=['50,620,500,540'])
# 繪製PDF文件的座標,定位表格所在的位置
table_df = tables[0].df
print(type(table_df))
print(table_df.head(n=6))
輸出的結果為:
<class 'pandas.core.frame.DataFrame'>
0 1 2 3
0 Student Pre-test score Post-test score Difference
1 1 70 73 3
2 2 64 65 1
3 3 69 63 -6
4 … … … …
5 34 82 88 6
總結
在具體識別PDF頁面中的表格時,除了指定區域這個引數,還有上下標、單元格合併等引數,詳細地使用方法可參考camelot官方文件網址:https://camelot-py.readthedocs.io/en/master/user/advanced.html。
注意:本人現已開通微信公眾號: Python爬蟲與演算法(微訊號為:easy_web_scrape), 歡迎大家關注哦~~
參考文獻
- camelot模組的官方文件:https://camelot-py.readthedocs.io/en/master/
- Camelot:一個從pdf抽取表格資料的Python庫:https://blog.csdn.net/qq_40925239/article/details/83153599