【pyhon笔记】钱迹x信用卡辅助对账(个人用)
背景
记账强迫症患者,苦于账本上的信用卡额度总跟实际的对不上,python小白的我决定写个小demo辅助对账。
涉及
- python BeautifulSoup
- SQLite
准备
- 信用卡账单eml(这里用的J行)
- 钱迹账单csv
关键步骤
解析并处理信用卡账单
使用BeautifulSoup组件,解析账单eml
# 读取账单eml
eml = open(source_path).read()
# 使用Parser解析eml
content = Parser().parsestr(eml)
bill = ""
# 深度优先遍历
for par in content.walk():
# 消息的有效内容是一个子EmailMessage对象的列表,则返回True,否则返回False
if not par.is_multipart():
content = par.get_payload(decode=True)
if len(content.strip()) != 0:
# 这里,会得到唯一的一个包含账单的html字符串
bill = content.decode(encoding='gbk')
# 这里需要重点注意
# 使用BeautifulSoup转化前,需要事先将换行符去掉
# 否则,带有换行符节点的标签对象会解析不出来,直接变成None
data = BeautifulSoup(bill.replace('<br>', '').replace('<br/>', ''), "html.parser")
搜索账单列表。通过分析账单,还款明细的开头如下所示是一个id为takeList的tbody
<tbody id=takeList>
然后,这个tbody还会包含一个唯一的tbody,这个tbody下面就是一条一条的还款明细了
# 得到还款明细列表
repayList = data.find("tbody", id="repayList").find("tbody")
同理,也能得到消费列表
takeList = data.find("tbody", id="takeList").find("tbody")
逐条解析消费明细,得到交易列表
bills = []
repayAmount = Decimal(0.00)
for repay in repayList.children:
# NavigableString类型,就是没有子节点的字符串
# BeautifulSoup会将注释也解析进去,主要就是为了排除注释
if not isinstance(repay, NavigableString):
bill = {}
bill["type"] = "repay"
for item in repay.children:
# 匹配日期 MM/dd
if re.match("\d\d/\d\d", str(item.string), flags=0):
bill["time"] = year + "-" + str(item.string).replace("/", "-")
# 匹配金额
elif re.match("CNY\d*\.\d*", str(item.string), flags=0):
amount = str(item.string)[3:]
bill["amount"] = amount
repayAmount += Decimal(float(amount))
bills.append(bill)
为了之后方面对账,就将上面的数据处理成了如下所示格式
{
"month": "2023-02",
"name": "信用卡08月",
"bills": {
"2022-02-22": [{
"type": "repay",
"channel": "BCM",
"time": "2022-02-22",
"amount": "2.00"
}]
},
"size": 1,
"start": "17"
}
处理钱迹账单
导入SQLite
为了方便搜索数据,我用钱迹账单csv生成了SQLite数据库文件
搜索钱迹数据
current = current + relativedelta(days=1)
endtime = current.strftime("%Y-%m-%d") + " 00:00:00"
conn = sqlite3.connect(db_dir)
cur = conn.cursor()
cur.execute("select *from qian_ji qj where 时间 >= '" + starttime + "' and 时间 < '" + endtime + "' and 账户1 ='" + 账户名称 + "'")
比对数据
因为信用卡的账单是一个月一个,所以我这边也是一次比对一个月。
从账单日第一天开始,一直到下个月的账单日前一天,逐日分别计算当天信用卡和钱迹的交易净值并比对
感想
算是花了不少时间,实际最后也没做出啥像样的东西,但至少整个过程下来,也是学到了不少东西。
至少,目的达成了————成功阻止了我自己手动去改账本上的账户金额。
后续再继续研究下其他渠道的账单。