成长很苦,进步很甜,希望我们大家每天都能够向上生长。

本文转载自https://sutune.me/2018/07/18/requests/

request相关类封装系本人封装

概述

前面我们介绍了接口测试工具:Postman和Jmeter。利用接口测试工具上手使用虽然容易,但是还是不够灵活。例如需要界面上各种配置,有时还需限定的语言脚本来辅助(Postman限定使用Js,Jmeter限定使用Java

因此,如果我们直接使用自己熟悉的语言编写代码来进行接口测试将会更加灵活方便,这里我们将使用Python来进行接口测试。

Requests

进行接口测试需要发送HTTP请求,Python最基础的 HTTP 库有 Urllib、Httplib2、Requests、Treq 等,这里我们推荐使用Requests库来进行接口测试。

Requests 基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。目前很多Python爬虫也使用Requests库。

官方文档摘要

Requests 口号为:“让 HTTP 服务人类”

Requests中文文档

Requests github项目主页

Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。

警告:非专业使用其他 HTTP 库会导致危险的副作用,包括:安全缺陷症、冗余代码症、重新发明轮子症、啃文档症、抑郁、头疼、甚至死亡。

用户见证

Twitter、Spotify、Microsoft、Amazon、Lyft、BuzzFeed、Reddit、NSA、女王殿下的政府、Amazon、Google、Twilio、Mozilla、Heroku、PayPal、NPR、Obama for America、Transifex、Native Instruments、Washington Post、Twitter、SoundCloud、Kippt、Readability、以及若干不愿公开身份的联邦政府机构都在内部使用。

功能特性

  • Keep-Alive & 连接池
  • 国际化域名和 URL
  • 带持久 Cookie 的会话
  • 浏览器式的 SSL 认证
  • 自动内容解码
  • 基本/摘要式的身份认证
  • 优雅的 key/value Cookie
  • 自动解压
  • Unicode 响应体
  • HTTP(S) 代理支持
  • 文件分块上传
  • 流下载
  • 连接超时
  • 分块请求
  • 支持 .netrc(用户配置脚本文件)

Requests安装

使用pip安装命令如下:

1
pip install requests

安装检测

打开cmd窗口,输入python 然后导入requests 如果安装成功没有任何提示

1
import requests

如果提示如下内容则说明安装失败

1
ImportError: No module named 'requests'

如果没有安装pip的参考:Python 安装与配置

Requests 基础应用

发送不同类型HTTP请求

requests库内置了不同的方法来发送不同类型的http请求,用法如下所示:

requestbasic.py

12345678910111213141516171819
import requests

baseurl='http://httpbin.org'

#发送GET类型的请求r=requests.get(baseurl '/get')print(r.statuscode)

#发送Post类型请求r=requests.post(baseurl '/post')print(r.statuscode)

#发送PUT类型请求r=requests.put(baseurl '/put')print(r.statuscode)

#发送Delete类型请求r=requests.delete(baseurl '/delete')print(r.statuscode)

执行结果,200是状态码表示发送请求成功。

1234
200200200200

参数传递

传递URL参数

一般在GET请求中我们使用查询字符串(query string)来进行参数传递,在requests库中使用方法如下:

requestbasic.py

12345678
import requests

baseurl='http://httpbin.org'

paramdata={'user':'zxw','password':'666'}r=requests.get(baseurl '/get',params=paramdata)print(r.url)print(r.statuscode)

执行结果

1234
C:Python35python.exe D:/apitest/requestsapi_test/params.pyhttp://httpbin.org/get?user=zxw&password=666200Process finished with exit code 0

传递body参数

在Post请求中,一般参数都在请求体(Request body)中传递,在Requests中用法如下:

123
formdata = {'user': 'zxw', 'passwd': '8888'}r=requests.post(baseurl '/post',data=form_data)print(r.text)

执行结果:

123456789101112131415161718192021
{    "args": {},    "data": "",    "files": {},    "form": {        "passwd": "8888",        "user": "zxw"    },    "headers": {        "Accept": "/",        "Accept-Encoding": "gzip, deflate",        "Connection": "close",        "Content-Length": "20",        "Content-Type": "application/x-www-form-urlencoded",        "Host": "httpbin.org",        "User-Agent": "python-requests/2.18.4"    },    "json": null,    "origin": "110.52.4.225",    "url": "http://httpbin.org/post"}

请求头定制

如果你想为请求添加 HTTP 头部,只要简单地传递一个 dictheaders 参数就可以了。

用法如下:

1234
formdata = {'user': 'zxw', 'passwd': '8888'}header={'user-agent':'Mozilla/5.0'}r=requests.post(baseurl '/post',data=form_data,headers=header)print(r.text)

返回值

123456789101112131415161718192021
{    "args": {},    "data": "",    "files": {},    "form": {        "passwd": "8888",        "user": "zxw"    },    "headers": {        "Accept": "/",        "Accept-Encoding": "gzip, deflate",        "Connection": "close",        "Content-Length": "20",        "Content-Type": "application/x-www-form-urlencoded",        "Host": "httpbin.org",        "User-Agent": "Mozilla/5.0"    },    "json": null,    "origin": "110.52.2.106",    "url": "http://httpbin.org/post"}

Tips:很多爬虫程序都会定制headers来避免被封,如下面爬取知乎页面元素就设置了请求头。

1234
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}r = requests.get("https://www.zhihu.com/explore",headers=headers)print(r.text)

响应内容

当请求发送成功之后,我们可以获取响应内容。如响应状态码,响应头信息、响应体内容。

123456789101112
formdata = {'user': 'zxw', 'passwd': '8888'}header={'user-agent':'Mozilla/5.0'}r=requests.post(baseurl '/post',data=formdata,headers=header)

#获取响应状态码print(r.statuscode)#获取响应头信息print(r.headers)#获取响应内容print(r.text)#将响应的内容以Json格式返回print(r.json())

返回结果

12345
200{'Access-Control-Allow-Origin': '', 'Content-Length': '342', 'Access-Control-Allow-Credentials': 'true', 'Content-Type': 'application/json', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.8.1', 'Date': 'Wed, 18 Jul 2018 06:33:55 GMT', 'Via': '1.1 vegur'}{"args":{},"data":"","files":{},"form":{"passwd":"8888","user":"zxw"},"headers":{"Accept":"/","Accept-Encoding":"gzip, deflate","Connection":"close","Content-Length":"20","Content-Type":"application/x-www-form-urlencoded","Host":"httpbin.org","User-Agent":"Mozilla/5.0"},"json":null,"origin":"110.52.2.106","url":"http://httpbin.org/post"}

{'files': {}, 'origin': '110.52.2.106', 'json': None, 'data': '', 'url': 'http://httpbin.org/post', 'headers': {'User-Agent': 'Mozilla/5.0', 'Content-Length': '20', 'Accept': '/*', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'Connection': 'close', 'Accept-Encoding': 'gzip, deflate'}, 'form': {'passwd': '8888', 'user': 'zxw'}, 'args': {}}

Requests 进阶应用

Cookie设置

设置cookie

通过cookies参数可以设置Cookie

request_advance.py

12345
import requests

cookie={'user':'51zxw'}r=requests.get(base_url '/cookies',cookies=cookie)print(r.text)

运行结果:

1
{"cookies":{"user":"51zxw"}}

获取cookie

请求百度首页,然后获取cookie,实现如下:

123456
# 获取cookier=requests.get('http://www.baidu.com')print(type(r.cookies))  print(r.cookies)for key,value in r.cookies.items():    print(key ':' value)

运行结果:

123
<class 'requests.cookies.RequestsCookieJar'><RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>BDORZ:27315

调用了 cookies 属性即可成功得到了 Cookies,可以发现它是一个 RequestCookieJar 类型,然后我们用 items() 方法将其转化为元组组成的列表,遍历输出每一个 Cookie 的名和值,实现 Cookies 的遍历解析。

超时

你可以让requests 在经过以 timeout 参数设定的秒数时间之后停止等待响应。防止某些请求没有响应而一直处于等待状态。

下面案例故意设置一个很小的超时时间,为了来看一下超时后的一个响应处理,但是实际测试过程中不要设置这短。

123
r=requests.get(base_url '/cookies',cookies=cookies,timeout=0.001)print(r.text)

超时响应异常

12
 raise ConnectTimeout(e, request=request)requests.exceptions.ConnectTimeout: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /cookies (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x00000152590199E8>, 'Connection to httpbin.org timed out. (connect timeout=0.001)'))

文件上传

Reqeuests 可以使用参数files模拟提交一些文件数据,假如有的接口需要我们上传文件,我们同样可以利用它来上传,实现非常简单,实例如下:

1234
#上传文件file={'file':open('zxwlogo.png','rb')}r=requests.post(baseurl '/post',files=file)print(r.text)

会话对象

会话(Session)

在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

比如你先进行了登录操作,然后打开个人中心详情页面,个人中心详情页面如何知道展示的是刚刚登录的这个用户的信息,那么这里就需要使用Session来存储相关信息。

在接口测试过程中接口之间经常有依赖关系,比如下面这两个请求一个是设置Cookie,另外一个是获取cookie,在没有Session保存机制的情况下,第二个接口无法获取第一个接口设置的Cookie值。

1234567
#设置cookier=requests.get(baseurl '/cookies/set/user/51zxw')print(r.text)

#获取Cookier=requests.get(baseurl '/cookies')print(r.text)

响应数据

123456789
{  "cookies": {    "user": "51zxw"  }}

{  "cookies": {}}

Request的会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie。具体使用如下:

12345678910
#生成会话对象s=requests.Session()

#设置Cookier=s.get(baseurl '/cookies/set/user/51zxw')print(r.text)

#获取Cookier=s.get(baseurl '/cookies')print(r.text)

运行结果

1234567891011
{  "cookies": {    "user": "51zxw"  }}

{  "cookies": {    "user": "51zxw"  }}

所以,利用 Session 我们可以做到模拟同一个会话,而且不用担心 Cookies 的问题,通常用于模拟登录成功之后再进行下一步的操作。

SSL证书验证

Requests 可以为 HTTPS 请求验证 SSL 证书,就像 web 浏览器一样。SSL 验证默认是开启的,如果证书验证失败,Requests 会抛出 SSLError:
如果不想验证SSL则可以使用verify参数关闭验证SSL。

下面是验证12306网站的证书。

1234
r=requests.get('https://www.12306.cn')#关闭验证SSL#r=requests.get('https://www.12306.cn',verify=False) print(r.text)

运行结果:

12
raise SSLError(e, request=request)requests.exceptions.SSLError: HTTPSConnectionPool(host='www.12306.cn', port=443): Max retries exceeded with url: / (Caused by SSLError(CertificateError("hostname 'www.12306.cn' doesn't match either of 'webssl

Tips:12306的证书是自己颁发给自己的,所以会出现认证失败。

代理设置

代理简介

代理(Proxy),也称网络代理,是一种特殊的网络服务,允许一个网络终端(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。

代理服务器位于客户端和访问互联网之间,服务器接收客户端的请求,然后代替客户端向目标网站发出请求,所有的流量路由均来自代理服务器的IP地址,从而获取到一些不能直接获取的资源。

对于有些接口,在测试的时候请求几次,能正常获取内容。但是一旦开始大规模频繁请求(如性能测试)服务器可能会开启验证,甚至直接把IP给封禁掉。
那么为了防止这种情况的发生,我们就需要设置代理来解决这个问题,在 Requests 中需要用到 proxies 这个参数,在爬虫中会常用到代理。

西刺免费代理IP

1234
#代理设置proxies={'http':'http://219.141.153.41:80'}r=requests.get(base_url '/get',proxies=proxies)print(r.text)

运行结果如下:可以看到origin参数即为我们设置的代理ip

1234567891011121314
{  "args": {},   "headers": {    "Accept": "text/html,application/xhtml xml,application/xml;q=0.9,/;q=0.8",     "Accept-Encoding": "gzip, deflate",     "Accept-Language": "en-US,en;q=0.5",     "Cache-Control": "max-age=86400",     "Connection": "close",     "Host": "httpbin.org",     "User-Agent": "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52"  },   "origin": "219.141.153.41",   "url": "http://httpbin.org/get"}

身份认证

很多接口都需要身份认证,Requests支持多种身份认证,具体使用方法如下:

下面案例主要验证了2种身份类型:BasicAuthdigestAuth

12345678910
from requests.auth import HTTPBasicAuthfrom requests.auth import HTTPDigestAuth

#身份认证-BasicAuthr=requests.get(baseurl '/basic-auth/51zxw/8888',auth=HTTPBasicAuth('51zxw','8888'))print(r.text)

#身份认证——DigestAuthr=requests.get(baseurl '/digest-auth/auth/zxw/6666',auth=HTTPDigestAuth('zxw','6666'))print(r.text)

运行结果:

123
{"authenticated":true,"user":"51zxw"}

{"authenticated":true,"user":"zxw"}

流式请求

有一些接口返回值比较特殊,不是单纯返回一个结果,而是多个结果,比如某个查询接口,返回值为排行榜前10的商品信息。

实践案例

请求接口如下:

1
http://httpbin.org/stream/{num}

num 表示返回结果集的数量,比如输入10
则会返回10个下面这种不同id的结果

12345
{"url": "http://httpbin.org/stream/10", "args": {}, "headers": {"Host": "httpbin.org", "Connection": "close", "Accept": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER", "Referer": "http://httpbin.org/", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8", "Cookie": "gaugesuniquehour=1; gaugesuniqueday=1; gaugesuniquemonth=1; gaugesuniqueyear=1; gaugesunique=1"}, "origin": "110.52.4.234", "id": 0}{"url": "http://httpbin.org/stream/10", "args": {}, "headers": {"Host": "httpbin.org", "Connection": "close", "Accept": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER", "Referer": "http://httpbin.org/", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8", "Cookie": "gaugesuniquehour=1; gaugesuniqueday=1; gaugesuniquemonth=1; gaugesuniqueyear=1; gaugesunique=1"}, "origin": "110.52.4.234", "id": 1}{"url": "http://httpbin.org/stream/10", "args": {}, "headers": {"Host": "httpbin.org", "Connection": "close", "Accept": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER", "Referer": "http://httpbin.org/", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8", "Cookie": "gaugesuniquehour=1; gaugesuniqueday=1; gaugesuniquemonth=1; gaugesuniqueyear=1; gaugesunique=1"}, "origin": "110.52.4.234", "id": 2}更多内容省略...

针对这种类型的接口我们对结果集的处理需要使用迭代方法iter_lines()来处理,具体使用如下:

12345678910111213
import json

r=requests.get(baseurl '/stream/10',stream=True)

#如果响应内容没有设置编码,则默认设置为utf-8if r.encoding is None:    r.encoding='utf-8'

#对响应结果进行迭代处理for line in r.iterlines(decode_unicode=True):    if line:        data=json.loads(line)        print(data['id'])

返回结果:

12345678910
0123456789

request相关类封装

class MyRequests:"""对request请求进行封装"""def __init__(self):""""创建请求会话"""self.my_session = requests.Session()def __call__(self, url, methmod="post", data=None, is_json=True, **kwargs,):# 因对外接口方式全部为post,默认给post,对于其他方式直接在post方法后进行拓展即可methmod = methmod.lower()if isinstance(data, str):try:data = json.loads(data)except Exception as e:print(e)data = eval(data)if methmod == "post":# 对于只需要header中token鉴权方式的接口可以省略这一步传参header = self.header if hasattr(MyRequests, 'header') else Noneif is_json:res = self.my_session.request(methmod, url, headers=header, json=data, **kwargs)else:res = self.my_session.request(methmod, url, headers=header, data=data, **kwargs)else:res = Noneprint("不支持{}的请求方法".format(methmod))return res.json()def close(self):return self.my_session.close()

本文由博客一文多发平台 OpenWrite 发布!

烂笔头:知识回顾-- request类相关相关推荐

  1. 好记性不如烂笔头-linux学习笔记4apache相关知识

    好记性不如烂笔头-linux学习笔记4apache相关知识 apache 启动有2种模式 1是prefork模式,每个进程对应一个线程,如果是比较稳定的平台,那么prefork模式是worker模式 ...

  2. JAVA基础知识回顾-----File类-----实用

    所在包:java.io 1.文件 Java对文件管理,主要用到了IO包下的File类:主要针对文件及文件目录名称的管理,不包括文件的内容        ①声明 Java代码   public clas ...

  3. phpcms后台系统怎么去掉html目录_电子笔记本 | 好记性胜过烂笔头?基于python3的知识管理系统...

    要记忆很多东西,感觉自己记不住,或者总是忘记细节,怎么办? 记笔记啊,最好是电子笔记,方便查找和整理. 常言道: 好记性不如烂笔头.再好的记性,随着时间的推移都会遗忘的,除非不断地巩固.所以才有烂笔头 ...

  4. Nginx+Keepalived+LVS高可用集群----相关知识回顾

    1.原理回顾 1.1.集群知识回顾 集群特点: 1)高性能performance. 一些需要很强的运算处理能力比如天气预报,核试验等.这需要上千台计算器协同来完成这个工作的,共同分担计算任务. 2)价 ...

  5. 涨知识!华为备忘录还能这样玩,难怪古人说好记性不如烂笔头

    涨知识!华为备忘录还能这样玩,难怪古人说"好记性不如烂笔头" 古人云:"好记性不如烂笔头!"这句话是我们从小一直听到大的,可是真的能够做到的,真的没有几位,毕竟 ...

  6. 好记性不如烂笔头-笔记记录方法公开

    见字如面,我是东北码农. 俗话说,好记性不如烂笔头,在工作学习中记笔记是很重要的.今天介绍一下自己在工作中如何记录笔记,以及给大家安利一下win10自带的OneNote. 1.记录什么 1.1.流水账 ...

  7. python 全栈开发,Day32(知识回顾,网络编程基础)

    python 全栈开发,Day32(知识回顾,网络编程基础) 一.知识回顾 正则模块 正则表达式 元字符 :. 匹配除了回车以外的所有字符\w 数字字母下划线\d 数字\n \s \t 回车 空格 和 ...

  8. 进来在看《How Tomcat Works》这本书,将读书笔记贴在这里,好记性不如烂笔头。

    进来在看<How Tomcat Works>这本书,将读书笔记贴在这里,好记性不如烂笔头.  最简单的一个服务器,一个很简单的结果.  HttpServer构建ServerSocket,每 ...

  9. 【springmvc+mybatis项目实战】杰信商贸-6.重点知识回顾

    1.重点知识回顾 Maven 1)覆盖仓库文件,实际企业开发,公司会架一个测试服务器,在测试服务器中架私服.我们开发人员的程序,都连接私服.当本地没有项目中要使用的jar,Myeclipse mave ...

最新文章

  1. 洛谷P3572 [POI2014]PTA-Little Bird
  2. 《编写高质量代码:改善c程序代码的125个建议》——建议20-6:尽量将循环嵌套控制在3 层以内...
  3. vbs的任务提醒程序
  4. pagehelper 不分页的解决方法
  5. Android 中的 Service 全面总结(二)
  6. 记录一次java.lang.ClassCastException的java类型转换异常解决方案-附最终解决方案
  7. java缓存内存泄漏_java – getMethod是缓存并导致内存泄漏
  8. C#操作操作类库五(字符串的常用扩展方法)
  9. AXURE9最全的WEB设计元件库(分享版).rplib
  10. 一文读懂 Linux 各发行版之间的联系和区别
  11. HarryPotter第一部—Aragog-1.0.2
  12. python随机密码生成以整数17为随机数种子_简述pythonpytorch 随机种子的实现
  13. 【PostgreSQL-15的 \watch命令】
  14. UNIX 系统家族树的详细历史(图)
  15. 【Python网络蜘蛛】:基础 - 爬虫的基本原理
  16. 计算机类核心期刊审稿与发表周期,一般核心期刊的发刊周期有多长
  17. contiki学习笔记 etimer部分
  18. 脑电数据处理分析——edf转mat及fft
  19. 面试题:寻找一个字符串中出现次数最多的字符以及出现的次数
  20. php分销系统小程序,小程序分销的功能有哪些?

热门文章

  1. anychat for android sdk,AnyChat For Android SDK
  2. QT构建套件详解,windgb下载。编译器,调试器
  3. 怎样利用MAC中自带的截图工具
  4. 镇魂歌~Qt5字符串
  5. 组态王仿真学习案例之石灰石断烧系统,拥有实时历史曲线,报表
  6. 基于SSM的服装设计供需系统设计与实现
  7. android 流量 mate9,华为mate9 pro肿么用省手机流量
  8. C语言-数组和指针-11(已有一个排号序的数组,要求输入一个数后,按原来的排序规律将它插入数组中)
  9. linux各个文件夹作用是什么,我的世界游戏文件夹目录作用介绍 各个文件夹都是什么用...
  10. 双目立体视觉摄像头模块开发搭建,含源代码、电路图