python自动化测试学习笔记合集三
上次我们学到了redis的一些操作,下面来实际运用以下。
这里我们先来学习一下什么是cookie和session。
什么是Cookie
其实简单的说就是当用户通过http协议访问一个服务器的时候,这个服务器会将一些Name/Value键值对返回给客户端浏览器,并将这些数据加上一些限制条件。在条件符合时,这个用户下次再访问服务器的时候,数据又被完整的带给服务器。
因为http是一种无状态协议,用户首次访问web站点的时候,服务器对用户一无所知。而Cookie就像是服务器给每个来访问的用户贴的标签,而这些标签就是对来访问的客户端的独有的身份的一个标识,这里就如同每个人的身份证一样,带着你的个人信息。而当一个客户端第一次连接过来的时候,服务端就会给他打一个标签,这里就如同给你发了一个身份证,当你下次带着这个身份证来的时候,服务器就知道你是谁了。所以Cookie是存在客户端的,这里其实就是在你的浏览器中。
Cookie中包含了一个由名字=值(name=value)这样的信息构成的任意列表,通过Set-Cookie或Set-Cookie2HTTP响应(扩展)首部将其贴到客户端身上。
Cookie的分类
这里Cookie主要分为两种:
会话Cookie:不设置过期时间,保存在浏览器的内存中,关闭浏览器,Cookie便被销毁
普通Cookie:设置了过期时间,保存在硬盘上
关于Session
上面我们知道了Cookie可以让服务器端跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果Cookie很多,这无形地增加了客户端与服务端的数据传输量,而Session的出现正是为了解决这个问题。
同一个客户端每次和服务端交互时,不需要每次都传回所有的Cookie值,而是只要传回一个ID这个ID是客户端第一次访问服务器的时候生成的,而且每个客户端是唯一的。这样每个客户端就有了一个唯一的ID,客户端只要传回这个ID就行了,这个ID通常是NANE为JSESIONID的一个Cookie。所以Session其实是利用Cookie进行信息处理的。
cookie和session的共同之处在于:cookie和session都是用来跟踪浏览器用户身份的会话方式。
cookie和session的区别是:cookie数据保存在客户端,session数据保存在服务器端。
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session,当然也没有绝对的安全,只是相对cookie,session更加安全
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE
cookie和session各有优缺点,所以将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中。
实例:
先来验证用session登录的程序,分析:
首先先设计一个登录的程序,生成session写入redis,然后设计一个查询程序,传入session进行校验。
第一次登录:从my_user表中验证用户是否存在,用户存在且密码正确的场合生成session(规则:(当前时间戳+username))存入redis。
第二次登录查看:
#1、先验证用户是否登陆,username,session #2、验证session是否正确,判断和redis里边是否一致 #3、如果一致返回查询结果 #4、如果不一致,提示session非法 # session不存在,则提示用户未登录 # session不一致,登陆失败 #在K-V中传入session
以下是常用工具,放在lib目录的tools文件中:
#常用工具 import pymysql,hashlib,time import redis from conf import setting ##def op_mysql(host,user,passwd,db,sql,port=3306,charset='utf8'): def op_mysql(sql):conn=pymysql.connect(host=setting.MYSQL_HOST,user=setting.USER,passwd=setting.PASSWORD,port=setting.PORT,db=setting.DB,charset='utf8')cur=conn.cursor(cursor=pymysql.cursors.DictCursor)cur.execute(sql)sql_start=sql[:6].upper()if sql_start=='SELECT':#取sql的前6位,判断它是什么类型的语句。res=cur.fetchall()else:conn.commit()#res='ok'cur.close()conn.close()return res
def op_redis(k,v=None,expired=0,db=0): #def op_redis(host,passwd,k,v=None,port=6379,db=1):#r=redis.Redis(host=host,password=passwd,port=port,db=db)r=redis.Redis(host=setting.REDIS_HOST,password=setting.REDIS_PASSWORD,port=setting.REDIS_PORT,db=db)if v:r.setex(k,v,expired)res='ok'else:#res=r.get(k).decode()#获取不到的时候返回none,none不能直接进行decode操作res=r.get(k)if res:res=res.decode()else:res='none'return resdef md5_password(st:str):#规定传参的类型必须是str类型#st = hashlib.md5()bytes_st=st.encode()m=hashlib.md5(bytes_st)return m.hexdigest()
#main.py
import flask,time,hashlib from lib.tools import op_mysql,op_redis,md5_password import json server=flask.Flask(__name__) @server.route('/login',methods=['post']) def login():username=flask.request.values.get('name','')password=flask.request.values.get('passwd','')sql="select * from my_user where username='%s';"%(username)if username and password:if op_mysql(sql):print(op_mysql(sql))if password==op_mysql(sql)[0]['passwd']:session=md5_password(str(time.time())+username)op_redis('session:%s'%username,session,expired=6000,db=2)response={'code':200,'msg':'登陆成功','session':session}else:response={'code':101,'msg':'密码不正确'}else:response={'code':102,'msg':'用户不存在'}else:response={'code':103,'msg':'用户名或密码不能为空'}return json.dumps(response,ensure_ascii=False)
启动服务后,在postman中调用127.0.0.1:8088/login?name=pei&passwd=123456,执行一个正确的用户登录,:
{"msg": "登陆成功", "code": 200, "session": "28b14dea0c7a668650fbb19f6364f482"}
查看到redis里边已经插入了一个session数据:
下面进行第二部,传入用户名、session,如果验证正确则查询中表中的数据:
@server.route('/getall',methods=['post','get']) def getall():username=flask.request.values.get('name')session=flask.request.values.get('session')k='session:%s'%(username)redis_session=op_redis(k,db=2)if username and session:if redis_session:if redis_session==session:sql="select red,blue from seq "response = op_mysql(sql)else:response={'code':101,'msg':'session非法'}else:response={'code':102,'msg':'未登录'}else:response={'code':103,'msg':'必填参数为空'}return json.dumps(response,ensure_ascii=False)
以上是在k-v参数中传入session值,如需需要在cookie中传入session,代码如下:
就是把session=flask.request.values.get('session')改为session=flask.request.cookies.get('session')则取值就是在cookie中进行取值了。
@server.route('/getall_cookie',methods=['post','get']) def getall_cookie():username=flask.request.values.get('name')session=flask.request.cookies.get('session')k='session:%s'%(username)redis_session=op_redis(k,db=2)if username and session:if redis_session:if redis_session==session:sql="select red,blue from seq "response = op_mysql(sql)else:response={'code':101,'msg':'session非法'}else:response={'code':102,'msg':'未登录'}else:response={'code':103,'msg':'必填参数为空'}return json.dumps(response,ensure_ascii=False)
在我们登录购物网站的话,如果勾选记住密码,一般情况下就是在客户端浏览器上添加了cookie,这样用户打开网站后后台会自动校验cookie信息,不用每次都传一次,如下是设置cookie的代码:
要在页面添加cookie需要先response=flask.make_response(),然后response.set_cookie('session',session)set上要添加的cookie信息
@server.route('/login_setcookie',methods=['post']) def login_setcookie():username=flask.request.values.get('name','')password=flask.request.values.get('passwd','')sql="select * from my_user where username='%s';"%(username)if username and password:if op_mysql(sql):print(op_mysql(sql))if password==op_mysql(sql)[0]['passwd']:session=md5_password(str(time.time())+username)op_redis('session:%s'%username,session,expired=6000,db=2)response=flask.make_response()response.set_cookie('session',session)msg={'code':200,'msg':'登陆成功','session':session}else:msg={'code':101,'msg':'密码不正确'}else:msg={'code':102,'msg':'用户不存在'}else:msg={'code':103,'msg':'必填参数为空'}return response
添加cookie后,我们在调用getall_cookie时只传入name,就能直接获取到seq表中的数据了。
补充:
mysql注入原理
上述代码中存在的sql语句如下:
sql="select * from my_user where username='%s';"%(username)
在获取username时,由于存在‘’,所以存在漏洞;
我们知道‘1’=‘1’是恒为真的,我们可以通过‘’,来模拟制造出这种恒等式,使sql在执行时跳过一些校验,从而进阶访问系统。
当我们输入name=“' or '1'='1”
我们将上述name的值带入sql如下:
sql="select * from my_user where username='' or '1'='1';"
我们在sqlyog中my_user表中执行这个语句,查询出了所有的用户信息,
在一些查询操作中,很容易产生漏洞,造成信息的泄露。
还有一种注入方式是:username="' show tabales ; --"
sql="select * from my_user where username='' show tabales ; --';"
sql语句中--表示注释掉后边的语句,这样就查询出了所有的表,可以对数据库随意进行操作。
为了防止sql的注入,在编写sql的时候我们尽量避免使用‘’,写成如下方式:
sql="select * from my_user where username=%s;",username
这样在传参的时候,可以直接传到输入的参数进行取值,例如:
def op_mysql_new(sql,*data):#第一个是位置参数,第二个是可变参数cur.execute(sql,data)#data是一个元祖,*data获取出所有传过去的参数print(cur.fetchall())
sql="select * from users where name=%s and passwd=%s;" name='pei' passwd='123456' op_mysql_new(sql,name,passwd)
###################################################33
传参: def test(a,b):print(a,b)li=[1,2] test(*li)#一个星代表把list里边的数据穿进去 d={'a':'123','b':'456'} test(**d)#两个星代表从字典里边的数据传进去
python自动化测试学习笔记-6urllib模块&request模块
python3的urllib 模块提供了获取页面的功能。
urllib.request.
urlopen
(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
- url: 需要打开的网址
- data:Post提交的数据
- timeout:设置网站的访问超时时间
直接用urllib.request模块的urlopen()获取页面,page的数据格式为bytes类型,需要decode()解码,转换成str类型。
import urllib.request# import json # import requests url="http://api.nnzhp.cn/api/user/stu_info?stu_name=xiaohei" req=urllib.request.urlopen(url) res=req.read().decode() print(res)
执行:
{
"error_code": 2,
"msg": "无结果"
}
urllib 中实现post数据请求
urlopen()的data参数默认为None,当data参数不为空的时候,urlopen()提交方式为Post。
url1='http://api.nnzhp.cn/api/user/login ' data={'username':'niuhanyang','passwd':'aA123456' } #urlencode()主要作用就是将url附上要提交的数据。经过urlencode()转换后的data数据为?username=niuhanyang&passwd=aA123456, ## Post的数据必须是bytes或者iterable of bytes,不能是str,因此需要进行encode()编码 data=urllib.parse.urlencode(data).encode('utf-8') #最终提交的url是http://api.nnzhp.cn/api/user/login?username=niuhanyang?passwd=aA123456 req=urllib.request.Request(url1,data=data) page=urllib.request.urlopen(req).read() print(page.decode())
执行查看结果:
{
"error_code": 0,
"login_info": {
"login_time": "20180129202722",
"sign": "7e4c46e5790ca7d5165eb32d0a895ab1",
"userId": 1
}
}
我们看到使用urllib会比较麻烦,需要转码,赋值等操作,request模块可以更加简便的完成请求操作,如下:
1、首先需要安装Request模块
pip install requests
2、导入request模块
import requests
各种接口操作如下:
import requests import json #发送无参数的get请求 url='http://www.baidu.com' req=requests.get(url) print(req.text)#返回的字符串类型#发送有参数的request请求 url1='http://api.nnzhp.cn/api/user/stu_info?stu_name=feifei' req1=requests.get(url1) print(req1.json())#返回的字典列表#发送post请求 url2='http://api.nnzhp.cn/api/user/login ' data={'username':'niuhanyang','passwd':'aA123456' } req=requests.post(url2,data)#发送的post氢气,第一个参数是url,第二个参数是请求的数据 print(req.json())#发送入参是json类型的post请求 url3='http://api.nnzhp.cn/api/user/add_stu' data={'name':'feifei','phone':'13121111112','grade':'1000' }req=requests.post(url3,json=data) print(req.json())#发送带有cookie的post请求 #添加cookie url4='http://api.nnzhp.cn/api/user/gold_add' data={'stu_id':230,'gold':88888 } cookies={'feifei':'a2b454c3830e20e7d9916f6b52d6a3a7'} req=requests.post(url4,data,cookies=cookies) print(req.json())#发送带有Referer请求的post请求 # url5='http://api.nnzhp.cn/api/user/all_stu' data={'Referer':'http://api.nnzhp.cn/' } req=requests.get(url5,headers=data) print(req.json())#下载文件请求url6='https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1517138333609&di=327abc49fc6d63fed19124cdf826d130&imgtype=0&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201510%2F17%2F20151017223821_ZSWBc.jpeg' r=requests.get(url6)#下载直接请求url然后进行保存 #print(r.status_code)#请求状态码是二进制 res=r.content#获取二进制格式 fw=open('feifei.jpg','wb') fw.write(res)#保存文件 fw.close()#上传文件url7='http://api.nnzhp.cn/api/file/file_upload' f=open('E:\\besttest\\python\\besttest_code\\练习\\day7笔记\\api\\feifei.jpg','rb') r=requests.post(url7,files={'file':f}) print(r.json()) #
#下载页面 url='http://www.runoob.com/python/python-intro.html' r=requests.get(url) f=open('python.html','wb') f.write(r.content) f.close()
python自动化测试学习笔记-6excel操作xlwt、xlrd、xlutils模块
python中通过xlwt、xlrd和xlutils操作xls
- xlwt模块用于在内存中生成一个xls/xlsx对象,增加表格数据,并把内存中的xls对象保存为本地磁盘xls文件;
- xlrd模块用于把本地xls文件加载到内存中,可以读取xls文件的表格数据,查询xls文件的相关信息;
- xlwt可以生成xls文件,xlrd可以读取已经存在的xls文件,但是如果要修改本地已经存在的xls文件,就需要用到xlutils模块。
- xlutils模块是xlrd和xlwt之间的桥梁,可以使用xlutils模块中的copy模块,拷贝一份通过xlrd读取到内存中的xls对象,就可以在拷贝对象上像xlwt中那样修改xls表格的内容,并保存到本地。
要使用这些模块首先要安装导入:
pip install xlrd
pip install xlwt
pip install xluntils
安装好后进行导入
import xlrd import xlwt from xlutils.copy import copy
#创建一个excel book=xlwt.Workbook() #添加一个sheet sheet=book.add_sheet('sheet1') #向sheet中添加数据,行、列、value值 sheet.write(0,0,'id') sheet.write(0,1,'name') sheet.write(0,2,'age') sheet.write(0,3,'sex') #保存xls,微软的office不能以xlsx为结尾,wps随意 book.save('peitest.xls')
执行后生成了一个excel文件,查看内容
但是像这样一个单元格一个单元格的插入又很浪费时间,我们可以用循环来实现,如下:
############################## #利用循环写数据 #创建一个excel book=xlwt.Workbook() #添加一个sheet sheet=book.add_sheet('sheet2') row=0 col=0 list=[['id','name','age','sex'],['01','wang','13','女'],['02','li','23','女'],['03','hang','34','男'],['04','wu','16','女'],['05','ma','22','女'] ] #循环行 for r in range(6):#循环列for c in range(4):#根据行和列找到要赋值的valuesheet.write(r,c,list[r][c])c+=1r+=1 #保存excel book.save('peitest.xls')
执行查看结果:
上述方法是已知数据的行和列来循环的,如果行和列太多的时候就不方便了,我们可以通过循环list来添加数据,如下:
#创建一个excel book=xlwt.Workbook() #添加一个sheet sheet=book.add_sheet('sheet3') list=[['id','name','age','sex'],['01','wang','13','女'],['02','li','23','女'],['03','hang','34','男'],['04','wu','16','女'],['05','ma','22','女'] ]r=0 for stu in list:c=0for s in stu:sheet.write(r,c,s)c+=1r+=1 book.save('peitest.xls')
执行查看结果:
读取excel的数据是通过xlrd模块来实现的,如下:
############################################################################### #读取excel数据 book=xlrd.open_workbook('peitest.xls') #获取sheet,通过index sheet=book.sheet_by_index(0) #获取sheet通过sheet名称 #sheet=book.sheet_by_name('sheet3') value=sheet.cell(0,0).value value1=sheet.cell(0,1).value value2=sheet.cell(0,2).value value3=sheet.cell(0,3).valueprint(value) print(value1) print(value2) print(value3)
执行查看结果:
id
name
age
sex
同样的,如果我们要读取出excel所有的数据,也可以用循环来实现:
#####################################33 #循环来实现读取excel数据 #打开excel book=xlrd.open_workbook('peitest.xls') #获取sheet sheet=book.sheet_by_name('sheet3') #获取sheet中的行数 row=sheet.nrows #获取sheet中的列数 col=sheet.ncols #获取每一行的数据 for i in sheet.get_rows():print(i) #获取某一行的数据,通过循环获取出所有数据 for r in range(row):print(sheet.row_values(r)) #获取某一列的数据,通过循环获取出所有数据 for c in range(col):print(sheet.col_values(c))
执行查看结果:
[text:'id', text:'name', text:'age', text:'sex']
[text:'01', text:'wang', text:'13', text:'女']
[text:'02', text:'li', text:'23', text:'女']
[text:'03', text:'hang', text:'34', text:'男']
[text:'04', text:'wu', text:'16', text:'女']
[text:'05', text:'ma', text:'22', text:'女']
['id', 'name', 'age', 'sex']
['01', 'wang', '13', '女']
['02', 'li', '23', '女']
['03', 'hang', '34', '男']
['04', 'wu', '16', '女']
['05', 'ma', '22', '女']
['id', '01', '02', '03', '04', '05']
['name', 'wang', 'li', 'hang', 'wu', 'ma']
['age', '13', '23', '34', '16', '22']
['sex', '女', '女', '男', '女', '女']
我们看到上面第一种方法,每一个数据都带一个text,不方便进行后续操作,所以一般用第二种方式来实现。
修改文件
#######################################
import xlrd import xlwt from xlutils.copy import copy #修改excel文件 #打开文件 book=xlrd.open_workbook('peitest.xls') #复制一份文件用于修改 book2=copy(book) #获取要修改的sheet sheet=book2.get_sheet(0) #修改指定的行和列 sheet.write(0,0,'序号') #保存为新的excel book2.save('peitest1.xls')
执行查看结果:
好了 这次就学习到这了哦!
还想学习的话,记得收藏及关注哦.
感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
① 2000多本软件测试电子书(主流和经典的书籍应该都有了)
② 软件测试/自动化测试标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python编程语言、API接口自动化测试、web自动化测试、App自动化测试(适合小白学习)
————————————————
⑤ Python学习路线图(告别不入流的学习)
在我的QQ技术交流群里(技术交流和资源共享,广告进来腿给你打断)
可以自助拿走,群号768747503备注(csdn999768747503备注(csdn999))群里的免费资料都是笔者十多年测试生涯的精华。还有同行大神一起交流技术哦。
————————————————
版权声明:本文为CSDN博主「自动化测试君」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Yanan990830/article/details/120874523
python自动化测试学习笔记合集三相关推荐
- python自动化测试学习笔记合集
python自动化测试学习笔记-1 一.什么是自动化 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程.直白的就是为了节省人力.时间或硬件资源,提高测试效率,便引入了通过软件或程序自动化执行 ...
- python自动化测试学习笔记合集二
python自动化测试学习笔记-4内置函数,处理json 函数.全局变量 写代码时注意的几点事项: 1.一般写代码的时候尽量少用或不用全局变量,首先全局变量不安全,大家协作的情况下,代码公用容易被篡改 ...
- Python学习笔记合集(总结)
Python学习笔记合集(总结) 第一天主要讲了Python基本语句(上) 注释 输出 标识符 多行语句 第二天主要讲了Python基本语句(下) 行与缩进 关键字 数据类型 第三天主要讲了impor ...
- (小甲鱼python)集合笔记合集一 集合(上)总结 集合的简单用法 集合的各种方法合集:子、交、并、补、差、对称差集、超集
一.基础复习 集合与字典区别 集合中所有元素都是独一无二的,并且也是无序的. 集合具有唯一性.无序性.有限性 >>> type({}) #字典 <class 'dict'> ...
- HTML基础学习笔记合集
HTML学习笔记 基础认知 基本概念 常用标签 排版标签 标题标签 段落标签 换行标签(单标签) 水平线标签(单标签) 文本格式化标签 图片标签(单标签) 音频标签(双标签) 视频标签(双标签) 链接 ...
- 江科大51单片机入门学习笔记合集
文章目录 软件下载 介绍 STC89C52RC 命名规则 芯片介绍 开发板介绍 逻辑运算 C语言语法 函数在C语言基础上做的拓展 重入函数 中断函数 外部函数 sfr sbit 51单片机最小系统组成 ...
- 【用pandas_alive几行代码绘制竞赛动图】全网首发pandas_alive数据可视化中文学习笔记合集,学不会来打我(配置好的venv虚拟环境+拿来即用测试代码+测试数据集+参数api解析)
目录 专栏说明 一.效果图展示 1.1 水平条形图 1.2 竖直条形图 2. 折线图 3. 散点图 4.饼状图 5. 气泡图 6.1 地理空间点图 6.2 多边形地理空间图 7.多个图表 8.城市人口 ...
- 【动画消消乐】纯CSS加载/过渡动画学习笔记合集(1-50)
Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 自我介绍一下 ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入 ...
- python基本使用-python基本用法笔记合集
PYTHONPATH PYTHONPATH是python moudle的搜索路径.即import xxx会从$PYTHONPATH寻找xxx. 中文编码问题 coding=utf-8 查看导入的包的路 ...
最新文章
- cmd运行Java中文乱码,无法加载主类Error: Could not find or load main class
- PullToRefreshScrollView下拉刷新开源组件分析
- 如何利用webmin在Linux主机中添加网站
- ADO.NET Entity Framework Extensions 简单应用
- webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode)
- 使用bootstrap的相关配置
- Visual Studio 剪切板新特性
- rz/sz命令参数解释
- 【Kafka】kafka Removed ✘✘✘ expired offsets in ✘✘✘ milliseconds.
- 企业做网络推广关键词设置的几点个人看法
- springboot 整合 shiro (Web Applications)避坑一 ,请看shiro官网
- [读书笔记]《Windows游戏编程之从零开始》(零)
- 计算机故障排除pdf,计算机常见故障排除方法【藏】.pdf
- 使用ceres库将经纬度坐标GCJ02到WGS84精确转换
- 测试Java Stream流 parralle与 sequential的效率
- 用计算机视觉描述机器人,一文读懂计算机视觉和机器人视觉
- 无线射频专题《射频基础,射频特征,波长,频率,振幅,相位》
- 网页三栏布局常用方法
- Linux字体相关文件存放的目录位置
- python constrain_python约束 – 约束金额
热门文章
- 终于好了,自动生成支付宝自定义收款码
- JITStack超融合一体机_高性能分布式存储_面向企业私有云
- 《程序原本-追溯程序原本之书》读书笔记
- 由“微博”的发展史预测“轻博客”的命途
- 基于计算机视觉的Android手机摄像头实现长度测量
- Qt操作Excel表格
- 你管这叫操作系统源码(二)
- 【思路】2021美国大学生数学建模竞赛(美赛)思路+参考文献获取/【2021美国大学生数学建模】
- 利用MQL进行MQL解析
- 解决伪原创视频 改变视频md5原创