|
背景
记账强迫症患者,苦于账本上的信用卡额度总跟实际的对不上,python小白的我决定写个小demo辅助对账。
涉及
- python BeautifulSoup
- SQLite
准备
关键步骤
解析并处理信用卡账单
使用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('
- ', '').replace('<br/>', ''), "html.parser")
复制代码 搜索账单列表。通过分析账单,还款明细的开头如下所示是一个id为takeList的tbody
- [/code]然后,这个tbody还会包含一个唯一的tbody,这个tbody下面就是一条一条的还款明细了
- [code]# 得到还款明细列表
- 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 ='" + 账户名称 + "'")
复制代码 比对数据
因为信用卡的账单是一个月一个,所以我这边也是一次比对一个月。
从账单日第一天开始,一直到下个月的账单日前一天,逐日分别计算当天信用卡和钱迹的交易净值并比对
感想
算是花了不少时间,实际最后也没做出啥像样的东西,但至少整个过程下来,也是学到了不少东西。
至少,目的达成了————成功阻止了我自己手动去改账本上的账户金额。
后续再继续研究下其他渠道的账单。
来源:https://www.cnblogs.com/yiusnow/p/17179108.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|