python发送网络请求是通过模块中的方法来实现的,模块定义好了请求的语法格式,只需要按照相应的语法格式对号入座写代码即可。

一般来说我们测试的都是基于HTTP和HTTPS的网络请求,python有很多自动带的原生模块和扩展模块均可以模拟网络请求。当然我们在实际工作中会遇到很多其他协议请求,如WebSocket等。

  本章以HTTP协议为例,采用原生模块和扩展模块对比的方式,给大家剖析一下原理。原理性的东西虽然广泛不被重视,但它对大家之后的学习是十分有好处的。

5.1 发送HTTP请求

5.1.1  requests模块

  python有很多模块都可以发送HTTP请求,包括原生的模块http.client,urlib2等,第三方模块requests等,都封装了发送HTTP请求的方法。由于原生的模块过于复杂,不推荐使用,之后所有的请求都是基于第三方模块requests进行的,该模块的好处在于简单,把请求的框架都搭建好了,只需要填入相应的参数数据,就能发送网络请求了。

  requests模块非原生模块,所有要使用还需要先进行安装,按照之前安装模块的方法,打开命令行(在运行中输入cmd),然后在命令行输入:

  pip install requests

  接前就会自动安装requests模块及其相关模块,然后就可以引入该模块使用其提供的方法了。

  import requests

  后面会通过一些实例来介绍requests的具体使用方法。

5.1.2  请求与响应

  HTTP就是发送请求和获取响应的一个过程,而requests模块只需要一步就能完成这样的一个过程,并且request支持所有的HTTP请求的方法和响应数据,先进行语法介绍:

  r = requests.方法(url, headers, data, ...)

  其中url参数为必填的,毕竟HTTP请求就是对指定的URL进行发送,其他各种参数可根据实际请求的需要选择性使用。

  发送请求后会获取响应结果,然后把结果赋值给变量,最后通过变量的属性值取出需要的结果,下面就是常用返回结果:

  r.headers  获取返回的头信息

  r.text    获取返回的主体(其实就是网页html)

  r.cookies  获取返回的cookies

  r.status_code  获取返回的状态码(通常会通过状态码判断请求是否成功)

  学会requests的请求方法和获取响应的结果,就可以开始网络请求的测试了,下面就通过代码实例来熟悉requests的模块吧。

5.1.3  请求参数

1.URL参数

  URL是唯一的必填参数,既然是网络请求,必须要有URL地址才能发送,就像快递一定要写目的地才能发件一样。先从最简单的HTTP请求讲起,请求一个静态页面,比如访问网易首页,通过抓包可以看到该请求是用的get方式发送的,所有要调用requests的get()方法来发送请求。

  以网易首页作为请求例子,实例代码:

  import requests  # 导入requests模块;

  test_url = "http://www.163.com"  # 定义url

  response = requests.get(test_rul)  # 实例化requests.get()方法

  print(response.status_code)  # 输出返回的状态码

  print(response.headers)  # 输出返回的头信息

  print(response.text)  # 输出返回的主体

  

  代码说明:

    1 导入requests模块;

    2 将网易首页的URL赋值到变量test_url中(这样的好处在于看起来清晰,也方便代码今后的维护);

    3 在get()方法中将变量test_url直接传入,即完成了带URL的get请求(结果会赋值到变量reponse中,reponse中包含了返回结果的所有数据,可以根据需要获取想要的数据);

    4、5、6 获取并打印返回的结果(状态码、头信息、主体)

  运行结果如下图: 

  可以看出通过requests发送的HTTP请求只有3行代码,就那么简单的一行代码完成整个请求。

  整个请求过程全被封装在方法之中,对于没有编码基础的测试人员来说再适合不过了。

2、headers  参数

  headers是最常用的参数之一,前面那个例子只是最简单的请求,没有带其他参数信息,而很多时候需要带入headers发送请求,才可以获取相应的请求结果。

还是以网易首页作为例子,如果是pc端的请求,会返回pc端的页,如果是手机端的请求,则返回手机端的页面,这时候就要带上headers参数的请求,通过浏览器的抓包工具可以看到headers有个字段“User-Agent",而服务器就是根据这个字段来判断访问的来源,如果需要模拟手机端请求,需要将“User-Agent"改为请求的手机型号。

  实例代码:

  import requests  test_url = "http://www.163.com"  h = {"User-Agent":"Android/H60-L01/4.4.2"}  # 将headers赋值到变量h中;  reponse = requests.get(test_url, headers=h)  # 在get()方法中加一个headers参数,然后将变量赋值给headers参数。  print(reponse.status_code)  print(reponse.headers)  print(reponse.text)

  

  运行结果如下:  

3、cookies  参数

  cookies也是最常用的参数之一,因为只要涉及登录后数据获取,都需要用到cookies参数,那么如何获取到cookies呢,一种是通过post发送登录请求,获取返回值的cookies属性(这个会在后面的实例中讲解),还有一种就是通过浏览器的网络抓包方式获取,在还不会熟练使用request模块的前提下,就先介绍如何通过抓包获取cookies。

  首先打开chrome浏览器,然后登录网易邮箱(或其它网站),接着按F12(或在网页右键,选择检查)打开开发者工具,抓取cookies的界面如下图:

  选择application中的cookies,点击对应的测试URL域名,再找到session属性并且domain是对应测试请求的域名,然后这条信息name和value对应的就是cookies了。

  cookies参数以字典的形式发送,只需要对应的将name和value传入即可。

  实例代码:

  import requests  c = {"JSESSIONID":"abcRPAFmBY_sqf2qRMmxw"}  test_url = "https://www.163.com/"  reponse = requests.get(test_url, cookies=c)  print(reponse.status_code)  print(reponse.headers)  print(reponse.text)

  代码说明:

    2 将浏览器抓取的cookies信息以字典的形式赋值到变量c之中;

    4 在get方法中加一个cookies参数,然后将变量c赋值给cookies参数,即完成了带着cookies信息的get请求。

  其实cookies也是可以通过headers参数传递的,只是不同之处在于cookies是以字典的形式发送的,而在headers之中cookies只是其中一个键,所以需要把cookies放到该键对应的值里面,而对应的值是以key=value的形式传入的,改一下代码。

  import requests  c = {"JSESSIONID":"abcRPAFmBY_sqf2qRMmxw"}  test_url = "https://www.163.com/"  reponse = requests.get(test_url, headers={"cookies":c})  # 此处cookies是作为headers的键值传入;  print(reponse.status_code)  print(reponse.headers)  print(reponse.text)

  代码说明:

    4 在get方法中将变量c赋值给headers参数中的cookies字段,即完成了带着cookies信息的get请求。

  以上的两种方法,推荐使用cookies参数,一方面把cookies单独分离出来,不用与其他headers的字段放在一起,让代码更清晰,另一方面通过post请求返回的cookies是可以直接赋值到cookies参数之中,不需要再做转换。

4、params 参数

  对于params参数可以存放请求的表单,并会以key1=value1&key2=value2&key3=value3的形式跟进URL之后发送,为了区分URL和参数,最好不要把表单放在URL之中,可以通过params参数进行发送, 上面网易邮箱的URL也是带着参数的,直接放在URL之中,如果使用params参数就可以把后面的参数和URL分离。

  还是以博客园登录界面为例,只是URL部分把参数进行分离,代码如下:

  import requests  # test_url = "https://passport.cnblogs.com/user/signin?ReturnUrl=https%3A%2F%2Fwww.cnblogs.com%2F"  test_url = "https://passport.cnblogs.com/user/signin"  p = {"ReturnUrl":"https%3A%2F%2Fwww.cnblogs.com%2F"}  reponse = requests.get(test_url, params=p)  print(reponse.status_code)  print(reponse.headers)  print(reponse.text)

  代码说明:

  4 将需要发送表单以字典的形式赋值到变量p之中。

  5 在get方法中加一个params的参数,然后将变量p赋值给params参数,即完成了带着params信息的get请求。

  如果不使用params参数,也可以直接把表单加在URL中,只是代码不清晰,所以不推荐直接把表单加在URL中。

5、data 参数

  data参数也是用于存放请求表单,是request模块中最重要的参数之一。

  在使用data之前,先来了解一下post提交数据类型,区别与params,params只有一种类型(字符串类型),而post可以提交4种类型的数据,至于需要提交什么类型的数据,取决于服务器接收的数据类型。post的数据类型需要和服务器接收的一致,不然服务器就无法正常识别post的数据,导致测试结果报错。就像协议一样,接收方预定接收哪种类型的表单,然后发头方按照接收方指定的协议发送表单,这样就完成了一个表单的提交。

  如何识别服务器接收的数据类型?最简单的方式还是抓包。抓取数据类型的界面如下:

  

  通过抓包可以看到,在request headers 中有一个content-type的字段,这个字段表示了post发送数据的类型,一般分为以下4种类型:

  第1种:content-type:application/json

    实际上,现在越来越多的人反application/json作为请求头,用来告诉服务器消息主体是序列化后的json字符串。由于json规范流行,除了低版本IE之外的各大浏览器都原生支持json.stringify,服务器端语言也都有处理json的函数,并且json格式支持比键值对更加复杂的结果化数据。

    

  第2种:content-type:application/x-www-form-urlencoded

    这是最常见的post提交数据的方式,浏览器的原生form表单,如果不设置enctype属性,那么最终就会以application/x-www-form-urlencoded方式提交数据。提交的数据按照key1=value1&key2=value2的方式进行编码,key和value都进行了URL转码,然后打包发送到服务器。

  第3种:content-type:multipart/form-data

    content-type为multipart/form-data方式,主要用于上传文件。需要注意的是同时form的enctype属性也要设置为multipart/form-data,才能正确提交并解析所传输的数据。

  第4种:content-type:text/xml

    它是一种使用http作为传输协议,XML作为编码方式的远程调用规范。考虑到XML结构还是过于臃肿,一般场景用json会更灵活方便,所以这种提交我们的工作中实际使用的不多,仅了解一下就可以了。

  最常见的是 第2种 类型,直接将数据以{key:value}的字典形式赋值给表单,然后通过request.post()中的data参数传递就可以了。

  以网易音乐为例,搜索一首歌曲,通过抓包可以看到content-type是application/x-www-form-urlencoded,网易音乐的数据类型抓取图如下:

  

  

  搜索一首”一次就好“,通过抓包会发现有进行加密,那就直接把加密后的内容放到form之中发送出去,网易音乐的表单抓取如下图:

  

  实例代码:

  import requests  test_url = "https://music.163.com/weapi/search/suggest/web?csrf_token="  f = {"params":"ShQVLipkE8Y/p89iMoKOX5whEin1ZyoKeXZJJe+rBg+8mrEQT3RaAR5UP5B+ayoKrPIVzxsVuuFA1askCPcBzRJ6qOoPsPz06xStotZZGTmHrzaz1RcbiRpYOOrZl8NC",\       "encSecKey":"9ac26cbd1a87fd9790fb1cc2f0a475a5cd24be6b73e1b516f86b00ab58b568c0d4303eb6314bbedf5adedb968f047f44bb6ebe1fd9cfa09339a781d762e8aba0184c8a57dc53d1717f89d5c85d02e635cec9e7610fac4faac33838a3f299a1aa672390e4430b21ee2ea03e37aee53d17d70973933ffdf3fc7872101a9ff973da"\       }  reponse = requests.post(test_url, data=f)  print(reponse.status_code)  print(reponse.headers)  print(reponse.text)

  代码说明:

    3 将需要发送的表单以字典形式赋值到变量form之中。

    4 在post方法中加一个data参数,然后将变量赋值给data参数,即完成了带着表单信息的post请求。

  运行结果如下图:

    

以上内容来自《python测试之道》——杨燕林、朱对洲、石赟 编著,若有侵权请联系删除。

转载于:https://www.cnblogs.com/liukang92/p/9634941.html

python测试之道第5章模拟网络请求相关推荐

  1. python测试之道电子pdf下载_Python接口自动化测试 PDF 下载

    相关截图: 资料简介: 本书主要介绍如何用Python实现接口自动化测试.全书主要内容包括接口基础.接口手工测试.编程前的准备.用Python处理MySQL数据库.用Python发送HTTP请求.用P ...

  2. python测试之道进阶_自动化测试进阶路线

    做了几年自动化测试,突然想就这个问题,总结一下自己以往的学习经历,踩过的坑,做一些深入的探讨. 抛开疑问,只做学术探讨 这次我们抛开所有的疑惑,比如自动化测试到底有什么用?自动化真的能提升效率么?学了 ...

  3. python测试之道进阶,Pytest-Mock 进阶用法详解

    一.什么是 Mock 测试? Mock测试就是在 测试过程 中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法.这个虚拟的对象就是Mock对象.Mock对象就是真实对 ...

  4. python测试之道pdf百度云_Python测试之道——笔记1

    引言 如果利用python做自动化测试的话,一些python相关的基础知识是必须要掌握的.常用的比如:python代码规范.变量与数据类型.运算.函数和字符串处理等. 语法规范 这里只介绍重点和常用的 ...

  5. python在线读-Python测试之道

    领取成功 您已领取成功! 您可以进入Android/iOS/Kindle平台的多看阅读客户端,刷新个人中心的已购列表,即可下载图书,享受精品阅读时光啦! - | 回复不要太快哦~ 回复内容不能为空哦 ...

  6. 《Google软件测试之道》—第2章2.4节与工具开发工程师Ted Mao的访谈

    本节书摘来自异步社区<Google软件测试之道>一书中的第2章2.4节与工具开发工程师Ted Mao的访谈,作者[美]James Whittaker , Jason Arbon , Jef ...

  7. 《Google软件测试之道》—第2章2.5节与Web Driver的创建者Simon Stewart的对话

    本节书摘来自异步社区<Google软件测试之道>一书中的第2章2.5节与Web Driver的创建者Simon Stewart的对话,作者[美]James Whittaker , Jaso ...

  8. 《Google 软件测试之道》摘录

    最近刚刚看完<Google 软件测试之道>,受益颇多,遂记录下: 只有在软件产品变得重要的时候质量才显得重要 第一章:谷歌软件测试介绍 角色介绍 SWE(Software Engineer ...

  9. 《Google软件测试之道》目录—导读

    内容提要 Google软件测试之道 每天,Google都要测试和发布数百万个源文件.亿万行的代码.数以亿计的构建动作会触发几百万次的自动化测试,并在好几十万个浏览器实例上执行.面对这些看似不可能完成的 ...

最新文章

  1. POJ 2955 Brackets (区间DP)
  2. 学生电脑哪个牌子好_柳州304不锈钢学生饭盒哪个牌子好_家典美日用品
  3. 论面向组合子程序设计方法 之 燃烧的荆棘
  4. vc通过COM方式调用CertEnroll
  5. office word中利用宏编程批量调节图片的亮度和对比度
  6. ad怎么批量改元器件封装_Altium Designer 批量修改元件封装的方法(修正)
  7. 为什么在释放锁的时候是从 tail 进行扫描
  8. 【ABAP系列】SAP ABAP模块-任意report作为附件以邮件形式发送
  9. 1.2 Coin 项目
  10. springboot转发http请求_Spring Boot2 系列教程(八)Spring Boot 中配置 Https
  11. r720换固态硬盘后如何重装系统_联想R720重装Winddows10无法识别固态硬盘咋办
  12. UI基础(四)之tableView (cell重用、原型cell、静态cell)/xib注意事项
  13. 可视化,别把简单内容复杂化
  14. 俞渝手撕李国庆:他是同性恋,李回应:变态精神病患者!大量细节惊呆网友...
  15. 【物联网专题】2.2_设备管理平台_什么是物模型?
  16. I3C协议Single Data Rate(SDR)模式研读(一):总线配置Bus Configuration
  17. 国际短信系统平台软件源码开发路由功能—移讯云短信系统
  18. ASP 仿 Monorail MVC 的实现思路
  19. 统计给定的n个数中,负数,零和正数的个数。
  20. ollyDbg 保存修改后的.exe文件

热门文章

  1. linux下用gcc如何生成预处理、汇编等文件
  2. 利用 CSS selector 改变悬停表格样式
  3. (转)IE的box模型显示bug
  4. 复旦大学跑步爱好者协会章程(终稿)
  5. hadoop 之DefaultStringifier
  6. hdu4909 状态压缩(偶数字符子串)
  7. 【C 语言】字符串拷贝 ( 指针使用前判空 | while 空语句 )
  8. 【Android 逆向】ELF 文件格式 ( ELF 文件简介 | ELF 文件结构 )
  9. 【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )
  10. WPF动画之后属性值无法改变