python csv转excel_使用 Python 把 PDF 转为 CSV 和 Excel(一)
杭州國立公證處-公正搖號 會不定期公布杭州各個樓盤的購房意向登記匯總表和搖號結果,里面公開的數據是很全面的,對于想要分析一波數據搞點事情的人來說,挺有吸引力的。
但當你興沖沖地去官網下載完數據,一看傻眼了,為啥這個數據是 PDF 格式的,明明可以上傳為 Excel 的。如果頁數少點的話,沒準可以手動粘貼到 Excel里,但當映入眼簾的是一個多達 500 頁的 PDF,想讓我手動粘到 Excel 是不可能的,這輩子都不可能。
身為一名互聯網行業的數據分析師,要是獲取到了數據卻只能眼睜睜的看著,沒法下手,這是絕對不允許的。
于是,開始搜 Python 從 PDF 中提取 Excel 表格的教程,第一個搜到的是 Tabula,專門用于從 PDF 中提取 Excel 表格,官網如下:tabula?tabula.technology
Github 地址在這里:chezou/tabula-py?github.com
先安裝一下,使用:
pip install tabula-py
特別注意的是,tabula-py 運行時依賴于Java 環境,所以還得安裝一下Java。
裝好后,用起來也非常簡單,下面是一個簡單的例子:
import tabula
tabula.convert_into('HZ_YaoHao.pdf', 'HZ_YaoHao.csv', output_format = 'csv')
其中 HZ_YaoHao.pdf 文件中的數據是這個樣子的:
只需要一行代碼,就可以把 PDF 文件中的表格轉為 csv,真的是相當簡單哪。
結果看一眼轉為 CSV 的數據,怎么有種亂不糟糟的感覺 。。。
對比一下原來的 PDF 文件,會發現,在涉及到 換行的地方,轉換的 CSV 文件都會出現問題,比如標題 是否無房家庭,就被拆成了是否無房、家庭,而且分布在文件中的不同行,還有查檔編號有兩行的,也會被拆分到不同的行,使數據看起來很亂。
看來問題不是這么簡單就解決的,不過如果 PDF 表格數據沒有換行,而且比較規整的話,使用 Tabula 的性價比還是非常高的,簡單一行代碼就能搞定。
需要注意的是,上述代碼默認只會轉化 PDF 的第一頁,想要轉換所有頁數的話,加一個 pages 參數,使 pages = 'all' 即可。
tabula.convert_into('HZ_YaoHao.pdf','HZ_YaoHao.csv',output_format='csv',pages='all')
接下來,又搜到了 pdfplumber,可以從 PDF 中提取出表格、文本、矩形和線條的信息,同時支持可視化調試,看上去挺高大上的。
Github 地址如下:jsvine/pdfplumber?github.com
先安裝一下:
pip install pdfplumber
使用一下試試:
import pdfplumber
pdf = pdfplumber.open('HZ_YaoHao.pdf')
print(pdf.pages)
pdfplumber 調用 Open 方法打開 PDF 文件,輸出 pages 信息,部分結果如下:
[, ,
... ]
可見,pdf.pages 返回的是一個列表,列表里是每一頁的 Page 對象,所以通過遍歷這個列表,就可以拿到 PDF 文件每一頁的信息。
我們來捋一下思路:先拿到 PDF 文件的某一頁,比如第一頁 pdf.pages[0],然后從中提取出表格數據,轉成 Pandas 中的 DataFrame 格式 ( 不懂 Pandas 的同學可以移步我的專欄:Python 數據分析利器 -- Pandas ),輸出為CSV 或 Excel 文件,搞定,代碼可以這樣實現:
import pdfplumber
import pandas as pd
# 打開 PDF 文件
pdf = pdfplumber.open('HZ_YaoHao.pdf')
# 獲取 PDF 文件的第一頁信息
page0 = pdf.pages[0]
# 從 PDF 中提取表格
table = page0.extract_table()
# 將表格數據轉化為 DataFrame 格式
yaohao_df = pd.DataFrame(table)
# 輸出第一行數據
print(yaohao_df.loc[0])
# 保存到 CSV 文件
yaohao_df.to_csv('yaohao.csv', index = False, header = True)
第一行輸出結果如下:
0 購房登記號
1 購房人姓名
2 購房人證件號碼
3 是否無房\n家庭
4 查檔編號
5 其他購房人及家庭成員
6 其他購房人及家庭成員證件號碼
Name: 0, dtype: object
可以看到,對于原表格中有換行的 是否無房家庭,轉化完后會多出一個換行符 \n 。
再來看一下 CSV 文件中的數據:
可以發現,是否無房家庭因為有換行符 \n,所以進行了換行,同理,A0004 和 A0005 兩行因為原 PDF 表格中有上下兩行,也進行了換行。也就是說,如果 PDF 表格中的某一個單元格有多行,pdfplumber 在解析其中的表格時都會添加一個 \n 的換行符,這樣問題就簡單了,把轉換后的所有字符串中的 \n 替換為空字符串,問題是不是就可以解決了,我們來嘗試一下,
在調用 yaohao_df.to_csv( ) 之前添加一行:
yaohao_df.replace(to_replace = r'\n', value = '', regex = True, inplace = True)
使用正則表達式,將 yaohao_df 中的所有 \n 替換為空,CSV 文件結果如下:
這樣的結果看起來就整齊多了,不足的是首行 0,1,2,3,4,5,6,讓人看起來不是很舒服,原因是PDF 表格中的標題行也被當成了 DataFrame 中的一行,這個需要特殊處理一下,同時上述程序只處理了第 1 頁,需要改成處理所有的頁碼,完整的程序如下:
import pdfplumber
import pandas as pd
pdf = pdfplumber.open('HZ_YaoHao.pdf')
total_pd = pd.DataFrame()
pdf_columns = list()
for page in range(len(pdf.pages)):
print(page)
if len(pdf.pages) > 0:
temp_table = pdf.pages[page].extract_table()
if page == 0:
temp_df = pd.DataFrame(temp_table[1:], columns = temp_table[0])
temp_df.columns = [ temp.replace('\n', '') for temp in temp_df.columns ]
pdf_columns = temp_df.columns
else:
temp_df = pd.DataFrame(temp_table)
temp_df.columns = pdf_columns
temp_df.replace(to_replace = r'\n', value = '', regex = True, inplace = True)
total_pd = pd.concat([total_pd, temp_df], ignore_index = True)
# 保存到 CSV 文件
total_pd.to_csv('yaohao.csv', header = True, index = False)
# 保存到 Excel 文件
total_pd.to_excel('yaohao.xlsx', header = True, index = False)
來看看最終的效果,CSV 和 Excel 文件各 547 行:
CSV 文件:
Excel 文件:
至此,杭州搖號 PDF 中的購房意向登記匯總表 數據就完美的轉化成了 CSV 和 Excel 格式,但當你試圖把它套用在搖號結果的 PDF 中時,卻發現根本不起作用,原 PDF 中的數據如下:
因為程序不會識別這是一個表格,看來搖號結果的 PDF 又是另一種處理思路了。
另一個問題,官網已經有 150 多個樓盤的數據了,一個一個去下載真的很麻煩啊,有沒有辦法一次性下載所有的 PDF 文件,然后一次性用程序處理呢?
當然可以啊,用 Python 寫個爬蟲抓一下數據,把所有文件存到某個文件目錄下,然后統一把該目錄下的 PDF 文件轉化為 CSV 和 Excel 文件就好啦,且聽下回分解。
總結
以上是生活随笔為你收集整理的python csv转excel_使用 Python 把 PDF 转为 CSV 和 Excel(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 异步接口同步返回_Dubbo客户端异步接
- 下一篇: td里面的内容加了br不起作用_刀圈TD