解析【支付宝】账单流水,PDF表格 转 Excel

风控贷后审核中,需要根据用户提供的账单流水,判断用户的还款能力,来辅助做放款决策,所以提取规格化数据是很重要的第一步。

一般情况下,用户提供的账单流水几乎都是zip压缩包,解压后是PDF文件格式,而账单流水几乎都是表格形式展示的。

那么 PDF表格 怎么转化为Excel呢?或者保存到数据库呢?

 

  • 主要用到 pdfplumber 包,下载:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ pdfplumber

  • 解析表头
# 导入
import pdfplumber
import re

    
with pdfplumber.open(input_file_path, password=password) as pdf:
        # 首页文本
        first_page_text = pdf.pages[0].extract_text()

        search_obj = re.search(r"兹证明:(?P<name>.*?)\(证件号码:(?P<id_card>.*?)\)在其支付宝账号(?P<account>.*?)中明细", first_page_text, re.M | re.I | re.S)
        if search_obj:
            user_name = search_obj.group('name').replace(' ', '').strip()  # 姓名
            id_card_no = search_obj.group('id_card').replace(' ', '').strip()  # 身份证
            account_number = search_obj.group('account').replace(' ', '').strip()  # 支付宝账号
            output_file_path = '支付宝|{}|{}|{}.xlsx'.format(user_name, id_card_no, account_number)  # 拼接文件名
            print('解析表头成功')
        else:
            print('解析表头失败')
  • 提取数据

使用进度条,可以查看当前解析进度,还可以省略大量日志,下载:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ tqdm

# 导入进度条
from tqdm import tqdm

print('开始读取数据')
result = list()
for index, page in enumerate(tqdm(pdf.pages)):  # 进度条
    table_list = page.extract_table()
    if table_list:
        result.extend(table_list)
  •  清洗数据
# 清洗数据
df = pd.DataFrame(result)

df.columns = df.iloc[2]  # 提取字段
df = df.iloc[3:]  # 去除脏数据
df = df.replace(' ', '', regex=True)  # 去除所有空格,注意顺序不能换

df['交易时间'] = df['交易时间'].replace('\n', ' ', regex=True)  # 时间格式
df = df.replace('\n|,', '', regex=True)  # 去除换行
df = df.reset_index(drop=True)  # 索引
df = df.fillna(np.NAN).replace('', np.NAN)  # 空值填充

df['交易时间'] = pd.to_datetime(df['交易时间'].str.strip(), errors='ignore')  # 时间格式
df = df.astype({'金额': 'float'}, errors='ignore')  # 修改类型
df['金额'] = np.where(df['收/支'] == '支出', -df['金额'], np.where(df['收/支'] == '收入', df['金额'], 0))

  • 保存数据
# 保存到文件
df.to_excel(output_file_path, index=False)

# 也可以保存到数据库(会自动建表)
df.to_sql(name="table_name", con=con, if_exists='append', index=False)

  • 完整代码:
# -*- coding: utf-8 -*-

import re
import pdfplumber
import numpy as np
import pandas as pd
from tqdm import tqdm


def parse_pdf_ZFB(input_file_path: str, password: str = '') -> bool:
    """
    解析解析支付宝账单流水,格式化为Excel
    input_file_path:pdf文件绝对路径
    password:密码
    """
    result = list()
    output_file_path = 'output_file_path.xlsx'  # 文件输出名

    with pdfplumber.open(input_file_path, password=password) as pdf:
        # 解析表头
        first_page_text = pdf.pages[0].extract_text()
        search_obj = re.search(r"兹证明:(?P<name>.*?)\(证件号码:(?P<id_card>.*?)\)的支付宝账户(.*?)支付宝账户 (?P<account>.*?)\n收支明细", first_page_text, re.M | re.I | re.S)
        if search_obj:
            user_name = search_obj.group('name').replace(' ', '').strip()  # 姓名
            id_card_no = search_obj.group('id_card').replace(' ', '').strip()  # 身份证
            account_number = search_obj.group('account').replace(' ', '').strip()  # 身份证
            output_file_path = '支付宝|{}|{}|{}.xlsx'.format(user_name, id_card_no, account_number)  # 拼接文件名
            print('解析表头成功')
        else:
            print('解析表头失败')

        print('开始读取数据')
        for index, page in enumerate(tqdm(pdf.pages)):  # 进度条
            table_list = page.extract_table()
            if table_list:
                result.extend(table_list)

    if result:
        # 清洗数据
        df = pd.DataFrame(result)
        df.columns = df.iloc[8]  # 字段
        df = df.iloc[9:]  # 去除脏数据
        df = df.replace(' ', '', regex=True)  # 去除所有空格,注意顺序不能换
        df['时间'] = df['时间'].replace('\n', ' ', regex=True)  # 时间格式
        df = df.replace('\n|,', '', regex=True)  # 去除换行
        df = df.reset_index(drop=True)  # 重置索引
        df = df.fillna(np.NAN).replace('', np.NAN)  # 空值填充
        df['时间'] = pd.to_datetime(df['时间'].str.strip(), errors='ignore')  # 时间格式
        df = df.astype({'收入': 'float', '支出': 'float', '账户余额': 'float'}, errors='ignore')  # 小数格式
        # 保存到文件
        df.to_excel(output_file_path, index=False)
        print('解析文件成功')
        return True
    else:
        print('解析文件失败')
        return False

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值