python学习笔记(六)网络编程、操作redis、接口开发

1.网络编程

'''
python自带的request,不好用,熟悉下即可
    from urllib.request import urlopen
    from urllib.parse import urlencode
    url = 'http://api.nnzhp.cn/api/user/login'
    d = {'username':'niuhanyang','passwd':'aA123456'}
    print(urlencode(d))
    # req = urlopen(url+'?'+urlencode(d))#get请求
    req = urlopen(url,urlencode(d).encode())#post请求

    print(req.read().decode())
'''
import requests

#get请求,带参数的url

url = 'http://api.nnzhp.cn/api/user/stu_info'
d = {'stu_name':'wangxiaoyu'}
r = requests.get(url,d)#发get请求

print('r.json:',r.json())#返回的是一个字典(想要去值的话用字典)
print('r.text:',r.text)#返回的是一个字符串(写文件或写数据库的时候用这个)
print('r.content:',r.content)#返回的是bytes类型的(图片或歌或电影的时候用),.decode()下就变成字符串了

测试结果:
r.json: {'error_code': 0, 'stu_info': [{'id': 23, 'name': 'wangxiaoyu', 'sex': '', 'age': 18, 'addr': '反正不是大北京', 'grade': '不知道什么座', 'phone': '15001208825', 'gold': 130}]}
r.text: {
        "error_code": 0,
        "stu_info": [
                {
                        "id": 23,
                        "name": "wangxiaoyu",
                        "sex": "",
                        "age": 18,
                        "addr": "反正不是大北京",
                        "grade": "不知道什么座",
                        "phone": "15668888888",
                        "gold": 130
                }
        ]
}
r.content: b'{\n        "error_code": 0,\n        "stu_info": [\n                {\n                        "id": 23,\n                        "name": "wangxiaoyu",\n                        "sex": "\xe5\xa5\xb3",\n                        "age": 18,\n                        "addr": "\xe5\x8f\x8d\xe6\xad\xa3\xe4\xb8\x8d\xe6\x98\xaf\xe5\xa4\xa7\xe5\x8c\x97\xe4\xba\xac",\n                        "grade": "\xe4\xb8\x8d\xe7\x9f\xa5\xe9\x81\x93\xe4\xbb\x80\xe4\xb9\x88\xe5\xba\xa7",\n                        "phone": "15001208825",\n                        "gold": 130\n                }\n        ]\n}'
# get请求,不带参数的url(下载音乐文件)
url = 'http://aliuwmp3.changba.com/userdata/userwork/1128447787.mp3'
r = requests.get(url)
fw = open('jjj.mp3','wb')#wb写二进制内容,只要写入的不是字符串的都用wb
fw.write(r.content)
fw.close()
# get请求,不带参数的url(下载图片文件)
url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1561875280914&di=94f9f0c99be2d47569b367b2589d8391&imgtype=0&src=http%3A%2F%2Fpic37.nipic.com%2F20140113%2F8800276_184927469000_2.png' r = requests.get(url) fw = open('wangxiaoyu.jpg','wb') fw.write(r.content) fw.close()
#post请求
url = 'http://api.nnzhp.cn/api/user/login'
data = {'username':'xxxxx','passwd':'123456'}
r = requests.post(url,data)
print(r.text)

测试结果:
{
        "error_code": 0,
        "login_info": {
                "login_time": "20190702135625",
                "sign": "a19224bd24ssec7f091e75c8e82af4dd",
                "userId": 9986
        }
}
# 传cookie 方法1--直接传cookie,需要一个一个拼
url = 'https://qun.qq.com/cgi-bin/qun_mgr/get_group_list'
d = {'bkn':258378860}
cookie = {'uin':'o0623455','p_uin':'o0623455','traceid':'1ea2f8b915','pgv_pvi':'9385568','pgv_si':'s388957184','skey':'@atZtguMbY','pt4_token':'uiwSSTbQcE8FlEFIuLwWCNFDaPmKLsVPTZgA_','p_skey':'dQ2dHJfBSNwEYKdrO1XhRQkCS9oRmsmu81MbQ_'}
r = requests.post(url,d,cookies = cookie)
print(r.json())
#传cookie 方法2--通过header传
#传header
url = 'https://qun.qq.com/cgi-bin/qun_mgr/get_group_list' d = {'bkn':258378860} header = {'cookie':'RK=hcphpgC5c3; ptcz=ed64c0db76823cb34ccec3c148351f571ed2c62a31484d74aea24b337a711547; pgv_pvid=4163240000; o_cookie=623342455; pac_uid=1_623342455; uin=o0623342455; pgv_info=ssid=s2689749875; p_uin=o0623342455; traceid=1ea2f8b915; pgv_pvi=9384045568; pgv_si=s388957184; skey=@atZtguMbY; pt4_token=uiwSSTbQcE8FlEFIuLwWCNK6ouHWfFDaPmKLsVPTZgA_; p_skey=dQ2dHJfBSNwEYKdrO1XhRQkCSQy1fQ69oRmsmu81MbQ_'} r = requests.post(url,d,headers = header) print(r.json())
# 上传文件
url = 'http://api.nnzhp.cn/api/file/file_upload'
r = requests.post(url,files = {'file':open('wangxiaoyu.jpg','rb')})#file是接口文档中参数名
print(r.text)

测试结果:
{
        "error_code": 0,
        "msg": "操作成功!"
}
# 用session的话,访问登录后的url不用再专门传cookie
#get请求--带参数的url
session = requests.session()
url = 'http://api.nnzhp.cn/api/user/stu_info'
d = {'stu_name':'wangxiaoyu'}
r = session.get(url,params = d)#post用data等于
print(r.text)

测试结果:
{
        "error_code": 0,
        "stu_info": [
                {
                        "id": 23,
                        "name": "wangxiaoyu",
                        "sex": "",
                        "age": 18,
                        "addr": "反正不是大北京",
                        "grade": "不知道什么座",
                        "phone": "15668888888",
                        "gold": 130
                }
        ]
}
#get请求--不带参数的url
session = requests.session()
url = 'https://www.cnblogs.com/xyxts/p/11118702.html'
# d = {'stu_name':'wangxiaoyu'}
r = session.get(url)#post用data等于
print(r.text)
#post请求
session = requests.session()
url = 'http://api.nnzhp.cn/api/user/login'
d = {'username':'wangxiaoyu','passwd':'123456'}
r = session.post(url,data=d)
print(r.json())
#上传文件
session = requests.session()
url = 'http://api.nnzhp.cn/api/file/file_upload'
r2 = session.post(url,files = {'file':open('wangxiaoyu.jpg','rb')})
print(r2.json())

2.操作redis

建立链接

r = redis.Redis(host='118.24.3.40',password='HK139bc&*',db=6,decode_responses=True)#0-15
                                   # decode_responses添加该属性后获取值的时候就不用手动将bytes类型通过decode转换成字符串了

针对字符串操作

# 1.存储,三种方式
# 方式1.存储
r.set('wangxiaoyu2','zui ai de ren shi wo ~')#key是'wangxiaoyu',value是18

# 方式2.添加过期时间存储,过多少秒删掉当前key
r.set('wangxiaoyu','nv',10)

# 方式3.分类存储
r.set('cnz_user:user_info:wangxiaoyu',18)
#2.获取
print(r.get('wangxiaoyu'))#如果建立redis链接的时候没有添加decode_responses=True属性,
# 那么这里获取到的就是一个bytes类型的返回值,否则返回的是字符串类型
# print(r.get('wangxiaoyu').decode())#没有添加decode_responses=True属性,需要decode下转换成字符串类型滴
#3.修改
r.set('wangxiaoyu','大声说出我爱你~')
# 4.删除
r.delete('cnz_user:user_info2:wangxiaoyu')#分类存储删除方式
r.delete('wangxiaoyu')#直接存储删除方式

针对hash值操作

# 针对hash值操作
# 1.存储
r.hset('cnz_user:user_info','lixiaokai','woaini')#cnz_user:user_info是大key,相当于一张表的表名
                                                 # 'lixiaokai','woaini'大value,相当于表中的一条数据,cnz_user:user_info里面存着很多条这种key和value的数据

# 2.批量存储
r.hmset('cnz_user:user_info',{'zhangshan':18,'lisi':19,'xiaoming':20})

# 3.设置过期时间,只能对大key设置过期时间,到时间后key下的所有数据都被清空,可以理解成表下的所有数据都被清空
r.expire('cnz_user:user_info',10)
# 4.获取key信息

# 4-1.获取key里面的xiaokey的值
print(r.hget('cnz_user:user_info','lixiaokai')) #获取小key的value值

测试结果:
woaini
# 4-2.获取大key下面的所有小key和value
print(r.hgetall('cnz_user:user_info'))#获取大key下的value值

测试结果:
{'lixiaokai': 'woaini', 'lixiaokai2': 'haha~I love you too ~'}
# 5.删除
# 5-1.删除指定的key(大key下面的某条小key和value)
r.hdel('cnz_user:user_info','lixiaokai2')
# 5-2.删除大key
r.delete('cnz_user:user_info')

其他操作

# 1.清除当前链接设置的db下的所有key
r.flushdb()
# 2.清除redis中所有db下的所有key
r.flushall()
# 3.获取所有db下的所有keys值
print('所有key值:',r.keys())
测试结果: 所有key值: [
'wangxiaoyu', 'wangxiaoyu2']
# 4.获取所有db下符合模糊匹配的keys值
print('模糊匹配到的key值:',r.keys('**yu2'))
# 测试结果:
模糊匹配到的key值: ['wangxiaoyu2']
# 5.获取指定key值是否存在,存在返回1,不存在返回0
print(r.exists('wangxiaoyu2'))
# 6.获取指定key类型
print(r.type('wangxiaoyu'))
print(r.type('cnz_user:user_info'))

测试结果:
string
hash

 案例

# 写一个注册和登录程序,信息存储到redis
#1、username,password,密码要存密文的
#2、要校验用户,如果用户不存在的话,才可以注册

import redis
import hashlib
import time

# 注册函数
def reg():
    # 在redis存用户名和密码,密码存密文
    r = redis.Redis(host='118.26.3.60',password='666666',db=6,decode_responses=True)#0-15

    username = input('username:').strip()
    password = input('password:').strip()

    db_username = r.get(username)#这里模拟的是redis中db为string类型时的获取方法,如果是hash类型,用hget
    if db_username:
        print('用户名已存在!')
    else:
        mp = hashlib.md5(password.encode())
        r.set(username,mp.hexdigest())
        print('注册成功!')

#
# if __name__ == '__main__':
#     reg()

# 登录函数
def login():
    # 在redis存用户名和密码,密码存密文
    r = redis.Redis(host='118.26.3.60',password='666666',db=6,decode_responses=True)#0-16

    username = input('username:').strip()
    password = input('password:').strip()

    db_username = r.get(username)
    if db_username:
        if db_username == hashlib.md5(password.encode()).hexdigest():
            print('%s,登录成功!现在的时间是:%s' % (username,time.strftime('%Y-%m-%d %H:%M:%S')))
        else:
            print('密码错误!')
    else:
        print('用户名不存在!')

# if __name__ == '__main__':
#     login()
测试结果:
username:wxytest
password:666666
注册成功!
username:wxytest
password:666666
wxytest,登录成功!现在的时间是:2019-07-03 13:41:17

3.接口开发

import flask
import json

server = flask.Flask(__name__)

@server.route('/get_req')
def mock_get_req():
    #模拟get请求
    m = {'code':1,'mes':'get请求,请求成功!'}
    return json.dumps(m,ensure_ascii=False)

@server.route('/post_req',methods=['post'])#methods=['post','get']及支持post又支持get
def mock_post_req():
    # username = flask.request.args.get('username')#username参数在url中时获取方法
    # username2 = flask.request.values.get('username2')#username2参数在body中时获取方法
    file = flask.request.files.get('f')#文件获取方法
    # cookie = flask.request.cookies.get('f')#cookie种的某一参数获取方法
    # header = flask.request.headers.get('Content-Type')#获取header中的某一参数方法
    # json = flask.request.json.get('f')#获取json参数方法
    file.save(file.filename)
    return 'aaaa'

# 0.0.0.0表示只要是在一个局域网内的都可以访问,debug为True时不用每次修改代码后都重启一下
server.run(host='0.0.0.0',port=8090,debug=True)

# 返回:{"code": 1, "mes": "get请求,请求成功!"}

# 浏览器访问接口:http://192.168.1.x:8090/get_req
# return 'hi,%s,欢迎登陆平台!' % username
# postman模拟浏览器访问接口:http://192.168.1.x:8090/post_req?username=wangxiaoyu
# 返回:hi,wangxiaoyu,欢迎登陆平台!

# return 'hi,%s,%s,欢迎登陆平台!' % (username,username2)
# postman模拟浏览器访问接口:http://192.168.1.x:8090/post_req?username=wangxiaoyu
# 并在body里传key为:username2 value为:lixiaokai的参数
# 返回:hi,wangxiaoyu,lixiaokoai,欢迎登陆平台!

# return 'aaaa',上传文件的时候returen随便写,不会显示到页面上,但必须有个返回值,否则虽然也能上传成功但是接口日志会报错
# postman模拟浏览器访问接口:http://192.168.1.x:8090/post_req
# 参数传一个file,名字叫f,内容随便传,文件类型不限(如,txt文件,图片文件,因为文件等)

 案例

import flask
import pymysql

'''
编写一个查看表信息的接口,且只能查看app_myuser,app_product,app_student这三张表
'''
server = flask.Flask(__name__)

host = '118.26.3.60'
port = 3306
username = 'xxx'
password = '123456'
db = 'xxx'

def op_mysql(sql):
    conn = pymysql.connect(host = host,port = port,user = username,password = password,db = db,charset = 'utf8')
    cur = conn.cursor(pymysql.cursors.DictCursor)
    cur.execute(sql)
    result = cur.fetchall()#获取结果方法1.内存大用这个方法:如果数据库量太大容易把内存填满,所以可以用下面直接循环游标一行一行取数据
    cur.close()
    conn.close()
    return result

@server.route('/get_table')
def show_table():
    table_name = flask.request.args.get('tn')
    if table_name:
        list = ['app_myuser','app_product','app_student']
        if table_name in list:
            sql = 'select * from %s ' % table_name
            return str(op_mysql(sql))
        else:
            return '抱歉!您无权查看该表信息!'
    else:
        return '请输入表名!'

server.run(host='0.0.0.0',port=8090,debug=True)


浏览器方法:http://192.168.1.xxx:8090/get_table?tn=app_student接口查看app_student下所有数据

你可能感兴趣的:(python学习笔记(六)网络编程、操作redis、接口开发)