最近有需求需要解析电子行程单(滴滴、美团、高德等)的数据,由于电子行程但都是PDF的文件,为此需要解析PDF,由于PHP对解析pdf方面较弱,所以选用了Python。过程是现将pdf转为csv,然后解析csv文件的数据。
Python 3.7.6
Java 1.8.0_121(tabula-py 是对 tabula-java 的封装,所以需要依赖 Java)
nignx 由于这边用到flask框架,该框架无法使用80端口,为了防止端口暴露,所以需要使用nginx做转发,该框架和转发后续文章讲解
flask==1.1.1 用到的框架
pdfminer.six==20200124 解析PDF的包
由于后面会单独讲flask,在此主要说一下pdfminer
from pdfminer.high_level import extract_text
from pdfminer.pdfparser import PDFSyntaxError
def _parse(file_path, line_count=0):
"""解析滴滴出行的行程单,表头行需要特别清洗"""
area = [266, 42.765625, 785.028125, 564.134375]
if line_count != 0:
area[2] = 3120.003125 + 31.2375 * line_count
dfs = tabula.read_pdf(file_path, pages="all", area=area)
num = len(dfs)
save_data = []
save_data.append(dfs[0])
if num == 0:
logging.error("no table found")
elif 1 < num:
for i in range(1, num):
area = [175, 42.765625, 785.028125, 564.134375]
area[2] = 3120.003125 + 31.2375 * line_count
dfs = tabula.read_pdf(file_path, pages=i + 1, area=didi_area)
save_data.append(dfs[0])
# 滴滴的表头行有一些多余的换行符,导致导出的 CSV 破损
for i in range(0, num):
save_data[i].columns = [name.replace('\r', ' ') for name in save_data[i].columns]
return save_data
上面是一个简单的读取文件内容的功能,支持多页读取,
area:控制读取内容的位置,由于第二页的数据位置和第一页不同,所以需要重新读取
然后将数据写入CSV
# data 读取的PDF数据
# output_path csv保存的路径
def _output_csv(data, output_path):
"""利用 DataFrame 自身的 API,导出到 CSV 格式"""
# 增加 BOM 头,否则不能双击Excel 直接打开CSV
with open(output_path, mode='wb') as output:
output.write(BOM_UTF8)
with open(output_path, mode='a', newline='') as output:
for i in range(0, len(data)):
data[i].to_csv(output, index=False)
以上就生成了CSV文件,后面就是通过取CSV文件数据就可以了。
项目地址: pdf2csv.