day08面向对象、jsonpath操作、写日志

一、上周作业

# 1.写一个程序,传入一个群号,把这个群里所有人的头像下载到本地,头像的名字
# 如果这个人有群备注,那么图片的名称就是名字.jpg,如果没有名称就取昵称
# 因为需要登录,所以需要cookie
# https://q4.qlogo.cn/g?b=qq&nk=857566034&s=140

1.分析

import requests
import os

#判断存在否,不存在创建文件夹
if not os.path.exists('qq_pics'):
    os.mkdir('qq_pics')
os.chdir('qq_pics')

max_count = 200
gc = '1078641913'
group_member_url = 'https://qun.qq.com/cgi-bin/qun_mgr/search_group_members'
size = 20#定义步长
brn = 2027956891#可变的
cookie = ''
#群里面最多200人
#0,20;21:41;42:62;....
count = 0
for j in range(0,max_count+1,20):

    headers = {
        'user-agent': 'Mozilla/5.0',
        'cookie': 'uin=o0544487209; skey=@EaiQXzjCW; RK=5NQIdFmjOh; ptcz=bfdea3df51354dc33cd2968594175f2ac8e8c56e2fd70a6067b2e92f1e78cd86; p_uin=o0544487209; pt4_token=c9ZNSP*7XNRwG5UgwGdvMbkYsXywb21nwYaqwaD39Ds_; p_skey=S-ceAUF1J0euCGX5Dqne6uBfHAGJp-RJqG5OSxRoA98_; traceid=9da1ab4551'
}

    data = { 'gc': gc,'st': j,'end': j+size+count,'sort': 0,'bkn': 2027956891}

    r = requests.post(group_member_url,data,headers=headers)
    members = r.json()
    count += 1
    if 'mems' in members:
        pic_url ='https://q4.qlogo.cn/g?b=qq&nk=%s&s=140'
        #all_count = members.get('count')
        mems = members.get("mems")
        for m in mems:
            qq = m.get("uin")
            #如果card的值取到了,就取card,没有取到取nick,非空即真
            name = m.get('card') if m.get('card') else m.get('nick')
            r = requests.get(pic_url %qq)
            with open(name+'.jpg','wb') as fw:
                fw.write(r.content)
            print('下载完成%s'%name)
    else:
        print('没有获取到群成员信息')
        break
View Code

2.登录并支付

# 2.写登录接口,登录成功之后返回seesionid:xxx
# 当前时间戳time.time()+username,做md5 生成sessionid,session过期时间,自己定义
# seesion会放到redis里面,
# redis里面存进入sessionid,fd:userid,time过期时间
# 2.2支付接口
# 建表table、存userid和money
# 1,20000
# /pay?sessionid=xxxx&money=90
#校验sessionid是否失效,取不到不是错的就是过期了,如果支付金额>余额数据库的就失败,<就成功扣钱
import time
import flask
import tools,json
import uuid
server = flask.Flask(__name__)

#登录
@server.route('/login',methods=['post','get'])
def login():
    username = flask.request.values.get('username','')
    password = flask.request.values.get('password','')

    if username.strip() and password.strip():
        #给密码加密
        p = tools.my_md5(password)
        #从mysql获取是否存在
        query_sql = 'select * from app_myuser where username= "%s" and passwd="%s";' % (username, p)
        user_result = tools.execute_sql(query_sql)
        if user_result:
            #生成sessionid,session是使用用户名+时间戳+uuid生成的
            session_str = '%s%s%s'%(username,time.time(),uuid.uuid4())
            #加密
            session_id = tools.my_md5(session_str)
            #获取ID,name,存入redis中
            user_id = user_result.get('id')
            #存入key.value,超时时间,注意写入方式
            tools.redis_str(session_id, '{"user_id":%s,"username":"%s"}' % (user_id, username), 600)
            return json.dumps({'code': '0', 'msg': '登录成功','sessionid':session_id},ensure_ascii=False)
        else:
            return json.dumps({'code': '-1', 'msg': '输入的用户名/密码错误'})
    else:
        return json.dumps({'code': '-1', 'msg': '不能为空'})



# print(uuid.uuid4())
#支付
@server.route('/pay',methods=['post','get'])
def pay():
    tools.logger.debug('进入支付接口')
    sessionid = flask.request.values.get('sessionid','')
    money = float(flask.request.values.get('money'))
    tools.logger.debug('请求参数:{}',flask.request.values)

    session = tools.check_session(sessionid)
    if session:
        user = json.loads(session)
        user_id = user.get('user_id')
        sql = 'select balance from app_myuser where id = %s;'%user_id
        tools.logger.debug('sql语句:{}',sql)
        balance = tools.execute_sql(sql).get('balance')
        if balance>=money:
            update_money = 'update app_myuser set balance = balance - %s where id = %s;' %(money,user_id)
            tools.execute_sql(update_money)
            return json.dumps({'code': 0, 'msg': '支付成功'},ensure_ascii=False)
        else:
            return json.dumps({'code': -1, 'msg': '余额不足'},ensure_ascii=False)
    else:
        return json.dumps({'code': 899, 'msg': '请登录!'},ensure_ascii=False)


if __name__ == '__main__':
    server.run(host='127.0.0.1',port=8999,debug=True)

#在网站上输入这个地址查询
#http://127.0.0.1:8999/login?username=niuhanyang2&password=1
#http://127.0.0.1:8999/pay?money=1&sessionid=bcaee6b6b1a2746f27b1dbc5488003f5
View Code

 二、tools文件新增

import traceback,hashlib

import pymysql
import redis
import xlwt
from loguru import logger
import sys

logger.remove()  # 清除它的默认设置设置
fmt = '[{time}][{level}][{file.path}:line:{line}:function_name:{function}] ||msg={message}'
# level file function module time message
logger.add(sys.stdout, level='INFO', format=fmt)  # 咱们本地运行的时候,在控制台打印
# logger.add('wxl.log',level='DEBUG',format=fmt,encoding='utf-8',enqueue=True,rotation='1 s',retention='10 seconds')#写在日志文件里面
logger.add('wxl.log', level='DEBUG', format=fmt, encoding='utf-8', enqueue=True, rotation='1 day',
           retention='10 days')  # 写在日志文件里面

MYSQL_INFO = {
    'host':'118.24.3.40',
    'user':'jxz',
    'password':'123456',
    'db':'jxz',
    'charset':'utf8',
    'autocommit':True

}

REDIS_INFO = {
    'host':'118.24.3.40',
    'password':'HK139bc&*',
    'port':'6379',
    'db':'4',
    'decode_responses':True #自动返回字符串
}

def execute_sql(sql,more=False):
    #连接数据库
    conn = pymysql.connect(**MYSQL_INFO) #xx=xxx,xx=xx
    cur = conn.cursor(pymysql.cursors.DictCursor)  # 游标
    try:
        cur.execute(sql)#没有问题,执行这句
    except:
        logger.error('sql错误,{}',traceback.format_exc())
        # print('sql不正确')#不正确走这句
        # traceback.print_exc()
    # else:
    #     return cur.fetchall() #None [{}]
    else:#执行完try执行else中的
        if more:
            return cur.fetchall() #None [{}]
        return cur.fetchone() #{'xx':'xx'}
    finally:
        conn.close()
        cur.close()

class Tool:

    @staticmethod
    def write_excel(name,data):
        book = xlwt.Workbook()
        sheet = book.add_sheet('sheet1')
        # 获取表头,写表头
        for index, key in enumerate(data[0]):#写表头
            sheet.write(0, index, key)
        for row, item in enumerate(data, 1): #写数据
            for col, value in enumerate(item.values()):
                sheet.write(row, col, value)

        book.save(name + '.xls')
        print('导出完成')

    # @staticmethod
    # def my_md5(s):
    #     s = str(s)
    #     s = s.encode()
    #     m = hashlib.md5(s)  # bytes,不可逆
    #     result = m.hexdigest()
    #     return result

def my_md5(s):
    s = str(s)
    s = s.encode()
    m = hashlib.md5(s)  # bytes,不可逆
    result = m.hexdigest()
    return result

def redis_str(key,value=False,expire_time=None):
    r = redis.Redis(**REDIS_INFO)
    if value:
        r.set(key,value,expire_time)
    else:
        return r.get(key)

def redis_hash():
    pass

#校验sessionid
def check_session(session_id):
    result = redis_str(session_id)
    if result:
        return result
    return False
View Code

三、写日志

import logging   #python自带的工具
import loguru #第三方的写日志
import sys,time
from loguru import logger
#debug #调试信息,最低的级别
#info #正常的提示信息
#waring #警告信息
#error #出错了 ,走不动  #50-100
#写日志是io操作,会影响内存,一般正式环境设置日志级别都是
#exception #程序出异常了  sql执行出错了
def fd():
    logger.remove() #默认的设置清楚掉,debug
    #设置日志级别
    #stdout程序的标准输出,操作系统print才能在屏幕中写东西
    # level file function module time message
    fmt = '[{time}][{level}][{file.path}:line:{line}:function_name:{function}] ||msg={message}'
    logger.add(sys.stdout,level='INFO',format=fmt)#本地运行,在控制台打印
    #写到日志文件中
    #enqueue=True异步写日志:先把日志放到消息队列里面,在启动一个线程,慢慢写进去,可以提高性能
    #rotation默认时间:
    #rotation可以设置大小,超过多大就产生一个新文件1 kb,500 m,1 g
    #rotation可以多长时间,1 day,1 hour
    #rotation几点创建新文件,00:00,1:00
    #retention删除日志,当前的日志不会受影响
    logger.add('fd.log',level='DEBUG',format = fmt,encoding='utf-8',enqueue=True,rotation='1 day',retention='10 days')#部署到服务器的时候写在日志文件中
    #超过20kb就会创建一个新的文件,最新的都是在不带日期中的
    # logger.add('demo1.log',rotation='500 MB') #文件过大就会重新生成一个文件
    # logger.add('demo1.log', rotation='01:00') #每天1点创建新文件
    # logger.add('demo1.log', rotation='2 week')# 2个星期文件时间过长就会创建新文件
    # logger.add('demo1.log', retention='7 days')#一礼拜后会清空除了当前日志之前的日志,
    for i in range(20):
        time.sleep(1)
        logger.debug('程序开始运行了')
        logger.debug('开始连接mysql')
        logger.info('mysql配置xxxx')
        logger.warning('警告,磁盘空间即将不足')
        logger.error('程序出错了')
        # logger.exception('出错了')#使用exception会出现NoneType:None

fd()
#同步==高并发,所以使用异步写日志
def write_log(msg):
    with open('a.log','a',encodong='utf-8') as fw:
        fw.write(msg)
View Code

四、jsonpath操作

s= {"ec":0,"errcode":0,"em":"","cache":0,"adm_num":3,"levelname":None,"mems":[{"uin":511402865,"role":0,"g":0,"join_time":1589360442,"last_speak_time":1600570983,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"u671du82b1u5915u62fe","qage":14,"rm":0},{"uin":475566024,"role":1,"g":0,"join_time":1589360443,"last_speak_time":1596195430,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"CC","qage":15,"rm":1},{"uin":616745045,"role":1,"g":0,"join_time":1589360443,"last_speak_time":1589360443,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"u5927u5e08u5144","qage":14,"rm":1},{"uin":1473732204,"role":1,"g":0,"join_time":1589360443,"last_speak_time":1596699591,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"u5b89u5927u53d4","qage":10,"rm":1},{"uin":1930890111,"role":2,"g":-1,"join_time":1589360638,"last_speak_time":1589363741,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"56","qage":9,"rm":1},{"uin":549313033,"role":2,"g":0,"join_time":1590131830,"last_speak_time":1597542612,"lv":{"point":0,"level":1},"card":"u767du5b87u9e4f","tags":"-1","flag":0,"nick":"u79e6u6b87","qage":12,"rm":1},{"uin":121654011,"role":2,"g":1,"join_time":1591326665,"last_speak_time":1597549705,"lv":{"point":0,"level":1},"card":"u8e6du8bfe-u66f9u4e3au7f8e","tags":"-1","flag":0,"nick":"u265dAimeeu00b7Toou2740","qage":14,"rm":1},{"uin":411732604,"role":2,"g":1,"join_time":1591326665,"last_speak_time":1591584091,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"u4e09u53f6u8349u7684u624bu6307","qage":14,"rm":1},{"uin":690763103,"role":2,"g":1,"join_time":1591326665,"last_speak_time":1599960754,"lv":{"point":0,"level":1},"card":"u674eu9ad8u82f1","tags":"-1","flag":0,"nick":"u4e24u6b21u65b9u7684u65cbu5f8b","qage":12,"rm":1},{"uin":1522503760,"role":2,"g":0,"join_time":1591326665,"last_speak_time":1598146137,"lv":{"point":0,"level":1},"card":"u79b9u6881","tags":"-1","flag":0,"nick":"u79b9u6881","qage":9,"rm":1},{"uin":635763064,"role":2,"g":1,"join_time":1592997221,"last_speak_time":1600572109,"lv":{"point":0,"level":1},"card":"u970du7d2bu9633","tags":"-1","flag":0,"nick":"u6f02u6d41u6d77u5cb8","qage":13,"rm":1},{"uin":857566034,"role":2,"g":1,"join_time":1593329449,"last_speak_time":1600565621,"lv":{"point":0,"level":1},"card":"u4ee3u723d","tags":"-1","flag":0,"nick":"u767du7fbdu5f52u697c","qage":12,"rm":1},{"uin":347158400,"role":2,"g":0,"join_time":1593345739,"last_speak_time":1599385077,"lv":{"point":0,"level":1},"card":"u6731u6210","tags":"-1","flag":0,"nick":"u9ea6u514b.vod","qage":16,"rm":1},{"uin":704096641,"role":2,"g":1,"join_time":1594023174,"last_speak_time":1600572110,"lv":{"point":0,"level":1},"card":"u803fu5a1f","tags":"-1","flag":0,"nick":"704096641","qage":13,"rm":1},{"uin":978502577,"role":2,"g":1,"join_time":1594883618,"last_speak_time":1599992058,"lv":{"point":0,"level":1},"card":"u5f20u4e39u96ea","tags":"-1","flag":0,"nick":"u3000u3000Amouru256eu66aeu5ff5","qage":9,"rm":1},{"uin":799614279,"role":2,"g":0,"join_time":1594884719,"last_speak_time":1600565607,"lv":{"point":0,"level":1},"card":"u9c81u6d25u5065","tags":"-1","flag":0,"nick":"u4e28u5bd2u5c10u6708u309e","qage":13,"rm":1},{"uin":695254152,"role":2,"g":0,"join_time":1594886366,"last_speak_time":1600572106,"lv":{"point":0,"level":1},"card":"u738bu7965u9f99","tags":"-1","flag":0,"nick":"u8ffdu68a6u8d64u5b50u5fc3","qage":13,"rm":1},{"uin":251202767,"role":2,"g":1,"join_time":1594943472,"last_speak_time":1600572310,"lv":{"point":0,"level":1},"card":"u9ad8u96ef","tags":"-1","flag":0,"nick":"u7d2bu8272u7cbeu7075","qage":16,"rm":1},{"uin":120617143,"role":2,"g":1,"join_time":1595481073,"last_speak_time":1596951515,"lv":{"point":0,"level":1},"card":"u7b71","tags":"-1","flag":0,"nick":"u6668u98ceu5915u96e8","qage":18,"rm":1},{"uin":357084975,"role":2,"g":1,"join_time":1595817181,"last_speak_time":1600572106,"lv":{"point":0,"level":1},"card":"u674eu97e9u97e9","tags":"-1","flag":0,"nick":"u2581u2581u5e7bu68a6u541fu8ff7u60d1u4e0du4f4fu7684u5fc3","qage":8,"rm":1},{"uin":296915611,"role":2,"g":-1,"join_time":1595927320,"last_speak_time":1600572383,"lv":{"point":0,"level":1},"card":"u9b4fu5f3a","tags":"-1","flag":0,"nick":"u8defu4ebau7532@u63d0u4e0du8d77u52b2","qage":13,"rm":1}],"count":48,"svr_time":1600572532,"max_count":200,"search_count":48,"extmode":0}

import jsonpath
#返回max_count的值为200
print(jsonpath.jsonpath(s,'$.max_count'))#返回的都是list
#返回第一个mems的昵称
print(jsonpath.jsonpath(s,'$.mems[0].nick'))
#可以模糊匹配
print(jsonpath.jsonpath(s,'$..level'))#取到所有leveld的值
#返回search_count的值
print(jsonpath.jsonpath(s,'$.search_count'))
View Code

五、my_db

import pymysql
from loguru import logger
import traceback

MYSQL_INFO = {
    'host':'118.24.3.40',
    'user':'jxz',
    'password':'123456',
    'db':'jxz',
    'charset':'utf8',
    'autocommit':True
}
class MySQL:
    def __init__(self,host,user,password,db,charset='utf8',autocommit=True):
        self.conn = pymysql.connect(user=user,host=host,password=password,db=db,charset=charset,autocommit=autocommit)
        self.cursor = self.conn.cursor()


    def __del__(self):
        self.__close()

    def execute(self,sql):
        try:
            self.cursor.execute(sql)
        except Exception:
            logger.error('sql执行出错,sql语句是{}',sql)
            logger.error(traceback.format_exc())

    def fetchall(self,sql):
        self.execute(sql)
        return self.cursor.fetchall()

    def fetchone(self,sql):
        self.execute(sql)
        return self.cursor.fetchone()

    def bak_db(self):
        pass

    def __close(self):
        self.cursor.close()
        self.conn.close()

if __name__ == '__main__':
    my = MySQL(**MYSQL_INFO)
    print(my.fetchall('select * from app_myuser;'))
    my.fetchone('select * from app_myuser where id=1;')
    my.fetchone('select * from app_myuser where id=1;')
    my.fetchone('select * from app_myuser where id=1;')
my_db

六、面向对象

#以前的#面向过程
'''
1.4s店看车,付钱
2.保险公司
3.车管所,办理临时拍照
4.缴税
5.车管所、上牌、行驶证
调用a b c 函数
执行者
'''



#面向对象==化零为整
'''
买车处->
#1.4s店看车,付钱
#2.保险公司
# 3.车管所,办理临时拍照
#4.缴税
#5.车管所、上牌、行驶证
调用car()
指挥者
'''
'''
类:一个模板,一个模型
对象:根据模板造出来的具体的东西
实例:根据模板造出来的具体的东西
实例化:把模板做成具体东西的过程
构造函数:类在实例化的时候,自动执行的函数2.如果要使用这个类,必须要传一些参数的时候,参数写在构造函数里面
self,this:本类对象
析构函数:实例被销毁的时候会自动执行
私有:只能通过self调用,不能通过实例调用;只能在类里面用,不能在类外面用 def __close(self):
类方法:公共的方法,直接可以通过类名来调用
不需要实例化,通过实例也可以调用
类变量:定义在类里面的变量
实例方法:必须实例化的时候才可以调用,参数里有self
静态方法:和一个普通的方法没有任何区别,和类也没有什么关系,只是定义在类里面而已
属性方法:一个看起来像变量的方法
继承:父子关系
python中没有封装和多态
面向对象的三大类型:封装、继承、多态(java强类型,python弱类型)
'''
#类名首字母大写,驼峰
#函数名、变量名:xx_xx,下划线
import time
class PresonManger:#经典类
    pass

class Person2():#新式类
    pass

class Person3(object):#新式类
    pass

#=================================
class Person:#
    #类变量
    country = 'Chain'
    def __init__(self,name,sex,country='Chain'):
        # 构造函数:类在实例化的时候,自动执行的函数
        #变量中只要加了self之后,变量在这个类中所有函数都可以用
        print('self的内存地址', id(self))
        self.name = name
        self.sex = sex
        self.__height = 200
        self.country = country
        self.birthday = time.time()
        self.cry()
        # print('我是构造函数')

    def __del__(self):
        #最后执行析构函数
        print('我是析构函数%s'% self.name)

    @property  #不能有参数,必须有返回值
    def age(self):
        return int(time.tiem() - self.birthday)

    def run(self):

        print('%s run...'% self.name)

    def fly(self):
        print('%s fly'% self.name)

    def cry(self):
        print('%s 呜呜呜'% self.name)

    def say(self):#实例方法
        print('my name is %s,sex is %s '% (self.name,self.sex))
        print('%s 斤' %self.__height)
        print('我的国籍式%s'%self.country)

    @classmethod#类方法
    def putonghua(cls):
        print(cls.country)
        print('会说普通话')

    @staticmethod#静态方法
    def suangua():
        print('test')

bm = Person('小黑','2.男')#实例化
print('self的内存地址',id(bm))
#bm 对象,实例
bm.run()
bm.country = 'Janpan'#类变量
Person.country = 'Janpan'#类方法
Person.putonghua()
Person.suangua()
Person.age#调用属性方法
bm.suangua()
bm.say()
# print(bm.__height) #私有的不可以使用

benz = Person('小白','')#实例化
print('self的内存地址',id(benz))
benz.fly() #相当于Person.fly(benz)
benz.say()
del bm
print('abc/////////////')
View Code

七、继承:

class Lw:
    def driver(self):
        print('开车')

    def make_money(self):
        print('挣5000钱')

class Xw(Lw):
    #重写1:直接全部重写
    def driver(self):
        print('开飞机✈')
    #重写2:先调用之前的方法,然后在执行新增的方法
    def make_money(self):
        super().make_money()
        print('再5000块钱')

a = Xw()
a.driver()
a.make_money()



#======多态========
class Car:#基类
    def __init__(self,name):
        self.name = name

    def run(self):
        print('%s run...' %self.name)

class Bmw(Car):
    def fly(self):
        print('fly...')

class Benz(Car):
    def swim(self):
        print('swim...')

class Audi(Car):
    def liting(self):
        print('liting...')

def run(obj):
    obj.run()

c1 = Bmw('宝马')
c2 = Benz('奔驰')
c3 = Audi('奥迪')

run(c1)
run(c2)
run(c3)

class E:
    def daka(self):
        pass

class E1:
    def daka(self):
        print('8:30')

class E2:
    def daka(self):
        print('9:30')

class E3:
    def daka(self):
        print('10:30')
View Code

八、总结:

原文地址:https://www.cnblogs.com/victory-0315/p/13734308.html