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 

posted @ 2019-01-18 15:25  quietwalk  阅读(2352)  评论(0编辑  收藏  举报