• Python 读取 支付宝账单并存储到 Access 中


    我有一个很多年前自己写的C#+Access的记账程序,用了很多年,现在花钱的机会多了,并且大部分走的支付宝,于是就想把账单从支付宝网站上下载下来,直接写入到Access,这样就很省心了。

    记账程序是长这个样子的:

    还有报表汇总模块儿:

    Access 主要表结构如下:

    支付宝支付流水下载下来如下:

    具体代码如下:

    table="收支记录表"
    path="C:\Users\user\Desktop\tmp\alipay_record_20190114.xlsx"
    
    #test_connect()
    read_excel(path)
    #-*-coding:utf-8 -*-
    import pypyodbc
    import xlrd
    from  ClassDef import *
    import CommonUtil
    import traceback

    def read_excel(path):
        workbook=xlrd.open_workbook(path)
        sheet=workbook.sheet_by_index(0)
        nrows=sheet.nrows
        ncols=sheet.ncols
        print(nrows, ncols)
    
        j=0
    
        for i in range(1, nrows):
            # pay_time=sheet.row_values(i,0)#付款时间
            # print(pay_time)
            #print(sheet.cell(i, 0).value)  # 指定行和列获取数据
    
            goodsName = sheet.cell(i, 5).value  #商品名称
            inOrOut = sheet.cell(i, 7).value  ## 收、支
            status = sheet.cell(i, 8).value  ## 交易状态
            # if (reason.find("收益发放") > -1):
            #     continue
            if inOrOut is not None and len(inOrOut.strip()) >0 and goodsName.find("收益发放") == -1
                    and goodsName.find("赚钱红包推荐奖励")==-1
                    and (status.find("交易成功")>-1 or status.find("等待确认收货")>-1):
                #print(i,inOrOut)
                ioRecord = InOutRecord()
    
                ioRecord.reason=goodsName################################## reason
                ioRecord.inOrOut=inOrOut[0:1]########################### 收/支
    
                payTimeStr = sheet.cell(i, 0).value
                if payTimeStr is not None :
                    # print (i, payTimeStr)
                    payTimeStr = payTimeStr[0:8]
                    dateStr = payTimeStr[0:4]
                    monthStr = payTimeStr[4:6]
                    dayStr = payTimeStr[6:8]
                    # value = datetime.datetime(payTimeStr) XXXX
                    # print(payTimeStr)
                    # print(dateStr)
                    # print(monthStr)
                    # print(dayStr)
    
                    #自动生成编号:先查当天有几条记录了
                    filterDate = dateStr[2:4]+monthStr+dayStr
                    numberStr,connStr=genAccessKeyAndTradeDate(filterDate, dateStr, monthStr, dayStr)
                    # print("编号===" + numberStr)
                    if len(numberStr) > 0:
                        ioRecord.numberStr = numberStr  #########################  编号
                    else:
                        print("eeeeeeeeeeeeeeeeeeeeeeee  " + "编号自动生成错误" + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
    
    
                    ioRecord.payDate=connStr###################################  日期
                    ##########################################################################
                    amount = sheet.cell(i, 6).value#金额
                    ioRecord.amount=amount
                    # print("金额==="+str(amount))
    
                    #交易来源地
                    tradeSource = sheet.cell(i, 3).value  # 交易来源地
    
                    #获取交易对方,来确认收支类型
                    tradeObject = sheet.cell(i, 4).value  # 交易对方
    
                    #获取收支具体类型,如衣、食、住、用、行等
                    ioRecord.type=getType(tradeObject)
                    #修正 type
                    if ioRecord.reason is not None:
                        if ioRecord.reason.find('打车')>-1:
                            ioRecord.type=''
                    #完善
                    ioRecord.reason=ioRecord.reason.strip()+""+tradeObject.strip()+""+""+tradeSource.strip()+""
                    # if len(ioRecord.reason)>15:#商品名称只取前15个字符
                    #     ioRecord.reason=ioRecord.reason[0:15]
                    ioRecord.comment=tradeObject.strip()
    
    
                    ret=insertRecord(ioRecord)#存储
                    #ret=insertTest();
                    #ret=test_insertRecord(ioRecord)
                    if ret==1:
                        print(str(j + 1) + "--" + str(
                            i) + "  " + ioRecord.numberStr + "  " + ioRecord.payDate + "  " + ioRecord.inOrOut + "  "
                              + str(ioRecord.amount) + "  " + ioRecord.type + "  " + ioRecord.reason + "---存储成功")
    
                    print("==============================================================================================")
    
                    j=j+1
    #记录当前已经记了几条账目了
    def getRecordCountByDate(date):
        conn,cur=connect_access()
        #sql="SELECT * FROM " + table+" where 编号 like"+date+""
        sql = "select * from 收支记录表  where 编号 like "+"'"+"%"+date+"%"+"'"
        #sql = "select * from 收支记录表  where 编号 =  "+"'"+date+"'"
        #sql = "select * from 收支记录表  where 编号 like "  + date
        #print(sql)
        cur.execute(sql)
        #cur.execute(sql,date)
        alldata = cur.fetchall()
        total_rows = len(alldata)
        # total_cols = len(alldata[0])
        # print("总行数 = %d" % ( total_rows))
        return total_rows
    #根据日期自动生成编号,并生成交易日期
    def genAccessKeyAndTradeDate(filterDate, dateStr, monthStr, dayStr):
        recordCount = getRecordCountByDate(filterDate)
        print("filterDate==="+filterDate)
        print("recordCount==="+str(recordCount))
        numberStr = ""
        if recordCount == 0:
            numberStr = filterDate + "01"
        elif recordCount > 0 and recordCount < 9:
            numberStr = filterDate + "0" + str(recordCount + 1)
        elif recordCount >= 9:
            numberStr = filterDate + str(recordCount + 1)
    
        connStr = dateStr + "/" + monthStr + "/" + dayStr
    
        return numberStr, connStr
    def getType(tradeObject):
        type=""
        if tradeObject is not None:
            if tradeObject.find('超市') > -1 or tradeObject.find('汇悦') > -1 or tradeObject.find(
                    '大王') > -1 or tradeObject.find('便利') > -1: 
                    type = ''
    
            if tradeObject.find('商品') > -1 or tradeObject.find('蔬菜') > -1 or tradeObject.find('奶吧') > -1:
                type = ""
    
            if tradeObject.find('条码支付-总部') or tradeObject.find('食品') > -1 or tradeObject.find(
                    '餐吧') > -1 or tradeObject.find('切面') > -1:
                type = ""
    
            if tradeObject.find('德青源') > -1 or tradeObject.find('') > -1:
                type = ""
    
            if tradeObject.find('') > -1 or tradeObject.find('') > -1:
                type = '宝宝'
    
            if tradeObject.find('移动') > -1:
                type = "通信费用"
    
            if tradeObject.find('地铁') > -1:
                type = ""
    
            if tradeObject.find('市妇幼') > -1 or tradeObject.find('御和堂') > -1 or tradeObject.find('医院') > -1:
                type = '医疗健康'
    
            if tradeObject.find('七匹狼') > -1 or tradeObject.find('南极人') > -1:
                type = ''
    
            if tradeObject.find('图书') > -1 or tradeObject.find('当当') > -1:
                type = '自我完善'
    
            if tradeObject.find('供电') > -1:
                type = '电费'
    
        return type
    #存储一条数据
    def insertRecord(ioRecord):
        if (ioRecord is not None):
            #printItemAllInfo(ioRecord)
            conn, cursor = connect_access()
            #sql = "insert into 收支记录表 (编号, 日期, 收支原因, 收支, 金额, 类型) values( %s, %s, %s, %s, %s, %s)"
            # sql = "insert into 收支记录表 (编号, 日期, 收支原因, 收支, 金额, 类型) " 
            #       "values(%s, %s, %s, %s, %s, %s)"
            createDate = CommonUtil.getCurrentDateStr()
            sql = "insert into 收支记录表 (编号, 日期, 收支原因, 收支, 金额, 类型,备注) values("
                  + "'"+ str(ioRecord.numberStr) + "'" +","
                  + "'" + str(ioRecord.payDate) + "'" + ','
                  + "'" + str(ioRecord.reason) + "'" + ','
                  + "'" + str(ioRecord.inOrOut) + "'" + ','
                  + "'" + str(ioRecord.amount) + "'" + ','
                  + "'" + str(ioRecord.type) + "'"+ ',' 
                  + "'" + str(ioRecord.comment+"_"+createDate) + "'" + ')'
    
            #sql = 'insert into 收支记录表 (编号, 日期, 收支原因, 收支, 金额, 类型) values('+str(ioRecord.numberStr)+','
            # +ioRecord.payDate+','+ioRecord.reason+','+ioRecord.inOrOut+','+float(ioRecord.amount)+','+ioRecord.type+');'
    
            # print("=======================================================================")
            # print(dataRow[16], dataRow[17], dataRow[18])
            #print(sql)
            #print(ioRecord.numberStr,ioRecord.payDate,ioRecord.reason,ioRecord.inOrOut,ioRecord.amount,ioRecord.type)
    
    
            #print(createDate)
            try:
                # cursor.execute(sql, (
                #     str(ioRecord.numberStr),str(ioRecord.payDate),str(ioRecord.reason),
                #     str(ioRecord.inOrOut),str(ioRecord.amount),str(ioRecord.type)))
                cursor.execute(sql)
                conn.commit()
                cursor.close()
                conn.close()
                return 1
            except Exception as e:
                traceback.print_exc()
                print("insertOnRecord() 出错,具体记录内容如下XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                printItemAllInfo(ioRecord)
                cursor.close()
                conn.close()
                return -1
    #获取数据库连接
    def connect_access():
        mdb = 'Driver={Microsoft Access Driver (*.mdb,*.accdb)};' 
              'DBQ=D:\个人\我的软件\PersonalAsistance_2012_04_13\PersonalAsistance\PersonalAsistance\bin\Debug\PADB.mdb'
        conn = pypyodbc.win_connect_mdb(mdb)
        cur = conn.cursor()
        return conn,cur

    总结:

    这里面有几个关键点:

    1、读Excel(这个不算,比较淘常见)

    2、生成Access表的主键,这个主键的规则是这样的:取年的最后两位,月的两位,日的两位,然后从01开始往后编码,有几条编到几;

    3、连接Access,读、写Access;

    python 代码已经放出来了,记账程序有需要的可QQ我:861712499 

  • 相关阅读:
    CUDA编程学习(一)
    数据挖掘领域的十大经典算法
    MATLAB代码加密生成.p文件
    如何读入文件下的图像序列
    什么是co-training
    Addthis使用
    html5新增及删除标签
    html5语法
    设置SecureCRT配色和解决乱码问题
    html5新增及废除属性
  • 原文地址:https://www.cnblogs.com/quietwalk/p/10287377.html
Copyright © 2020-2023  润新知