另類爬蟲:從PDF文件中爬取表格數據

簡介

  本文將展現一個稍微不同點的爬蟲。
  以往咱們的爬蟲都是從網絡上爬取數據,由於網頁通常用HTML,CSS,JavaScript代碼寫成,所以,有大量成熟的技術來爬取網頁中的各類數據。此次,咱們須要爬取的文檔爲PDF文件。本文將展現如何利用Python的camelot模塊從PDF文件中爬取表格數據。
  在咱們的平常生活和工做中,PDF文件無疑是最經常使用的文件格式之一,小到教材、課件,大到合同、規劃書,咱們都能見到這種文件格式。但如何從PDF文件中提取其中的表格,這倒是一個大難題。由於PDF中沒有一個內部的表示方式來表示一個表格。這使得表格數據很難被抽取出來作分析。那麼,咱們如何作到從PDF中爬取表格數據呢?
  答案是Python的camelot模塊!
  camelot是Python的一個模塊,它可以讓任何人輕鬆地從PDF文件中提取表格數據。可使用如下命令安裝camelot模塊(安裝時間較長):html

pip install camelot-py

camelot模塊的官方文檔地址爲:https://camelot-py.readthedoc...
  下面將展現如何利用camelot模塊從PDF文件中爬取表格數據。python

例1

  首先,讓咱們看一個簡單的例子:eg.pdf,整個文件只有一頁,這一頁中只有一個表格,以下:web

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文件以下:函數

輸出的csv文件

例2

  在例2中,咱們將提取PDF頁面中的某一區域的表格的數據。PDF文件的頁面(部分)以下:spa

Statistics-Fundamentals-Succinctly.pdf第53頁

爲了提取整個頁面中惟一的表格,咱們須要定位表格所在的位置。PDF文件的座標系統與圖片不同,它以左下角的頂點爲原點,向右爲x軸,向上爲y軸,能夠經過如下Python代碼輸出整個頁面的文字的座標狀況:.net

import camelot

# 從PDF中提取表格
tables = camelot.read_pdf('G://Statistics-Fundamentals-Succinctly.pdf', pages='53', \
                          flavor='stream')

# 繪製PDF文檔的座標,定位表格所在的位置
tables[0].plot('text')

輸出結果爲:code

UserWarning: No tables found on page-53 [stream.py:292]

整個代碼沒有找到表格,這是由於stream方法默認將整個PDF頁面看成表格,所以就沒有找到表格。可是繪製的頁面座標的圖像以下:

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.readthedoc...

注意:本人現已開通微信公衆號: Python爬蟲與算法(微信號爲:easy_web_scrape), 歡迎你們關注哦~~

參考文獻

  1. camelot模塊的官方文檔:https://camelot-py.readthedoc...
  2. Camelot:一個從pdf抽取表格數據的Python庫:https://blog.csdn.net/qq_4092...
相關文章
相關標籤/搜索