1. 简介
Requests库是由python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,它在做网络请求上会比urllib使用更加方便。
2. 安装
直接使用pip安装即可
pip install requests
1. 请求方式
requests包含多种请求方式:
2. 基本用法
这里只介绍常用的GET请求和POST请求
2.1 GET请求
GET请求中的参数包含在URL里面,并且数据是明文的,可以在URL中看到。
GET请求提交的数据最多只有1024字节。
以实验网址为例(http://httpbin.org/get)
基本请求:
import requests
__author__='Evan'
r=requests.get(url='http://httpbin.org/get') # 使用GET请求访问
print(r.text) # 打印网页的HTML文本
打印结果:
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"origin": "12.192.229.251, 12.192.229.251",
"url": "https://httpbin.org/get"
}
可以发现,我们成功的发起了GET请求,返回结果中包含请求头、URL、IP等信息。
那么,对于GET请求,如果要附加额外的信息,要怎么添加呢?
使用params参数构造带请求参数的GET请求:
import requests
__author__='Evan'
# 请求参数
params={
'name': 'Evan',
'age': '24'
}
r=requests.get(url='http://httpbin.org/get', params=params) # 带请求参数的GET请求
print(r.text)
打印结果:
{
"args": {
"age": "24",
"name": "Evan"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"origin": "12.192.229.251, 12.192.229.251",
"url": "https://httpbin.org/get?name=Evan&age=24"
}
可以看到设置的params参数已经起作用了,不过还有一种方法也可以提供请求参数,就是构建完整的URL,因为GET请求的参数会包含在URL里面。
使用 urlencode模块 将字典序列化为GET请求参数:
import requests
from urllib.parse import urlencode
__author__='Evan'
# 请求参数
params={
'name': 'Evan',
'age': '24'
}
r=requests.get(url='http://httpbin.org/get?' + urlencode(params))
print(r.text)
打印结果:
{
"args": {
"age": "24",
"name": "Evan"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"origin": "12.192.229.251, 12.192.229.251",
"url": "https://httpbin.org/get?name=Evan&age=24"
}
可以看到结果和使用params参数的GET请求是一样的。
2.2 POST请求
POST请求大多在表单提交时发起。比如一个登陆表单,输入用户名和密码后,点击“登陆”按钮,这通常会发起一个POST请求,其数据通常以表单的形式传输,表单数据会放在请求体中,而不会体现在URL中,所以提交的数据是保密的,不会泄露敏感信息,并且 POST请求提交的数据大小没有限制。
以实验网址为例(http://httpbin.org/post)
基本请求:
import requests
__author__='Evan'
# 请求参数
data={
'name': 'Evan',
'age': '24'
}
r=requests.post(url='http://httpbin.org/post', data=data) # 使用POST请求访问
print(r.text)
打印结果:
{
"args": {},
"data": "",
"files": {},
"form": {
"age": "24",
"name": "Evan"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "16",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"json": null,
"origin": "12.192.229.251, 12.192.229.251",
"url": "https://httpbin.org/post"
}
可以发现,其中form部分就是我们提交的数据,这就证明POST请求成功发送了。
requests还可以模拟提交一些数据,比如上传文件,要怎么添加呢?
使用files参数构造带上传文件的POST请求:
import requests
__author__='Evan'
files={'file': open('haimianbaobao.ico', 'rb')} # 文件路径
r=requests.post(url='http://httpbin.org/post', files=files) # 带上传文件的POST请求
print(r.text)
打印结果:
{
"args": {},
"data": "",
"files": {
"file": "data:application/octet-stream;base64,R0lGODlhkQCCAHAAACH5BABBAAAALAAAAA...="
},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "8732",
"Content-Type": "multipart/form-data; boundary=c15f3180298f305a48359831993ed6b8",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"json": null,
"origin": "12.192.229.251, 12.192.229.251",
"url": "https://httpbin.org/post"
}
以上省略部分内容,可以发现,里面包含files这个字段,而form字段是空的,这证明文件上传部分会单独有一个files字段来标识。
3. 高级用法
现在大部分网站都有反爬机制,所以在请求网页的时候一般都要添加请求头才可以得到响应,某些网站限制登陆时还要设置cookies等,下面介绍一些常用的高级用法。(POST请求和GET请求同理,这里以GET请求为例)
3.1 添加请求头
请求头,用来说明服务器要使用的附加信息,比较重要的信息有Cookie、Referer、User-Agent等
下面简要说明一些常用的请求头信息:
看到这相信你已经了解请求头中大部分参数的含义了,现在开始用程序实现这些功能
使用headers参数添加”User-Agent“:
import requests
__author__='Evan'
# 请求头参数
headers={
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/78.0.3904.108 Safari/537.36'
}
r=requests.get(url='http://httpbin.org/get', headers=headers) # 带请求头的GET请求
print(r.text)
打印结果:
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
},
"origin": "12.192.229.251, 12.192.229.251",
"url": "https://httpbin.org/get"
}
可以看到,“User-Agent”已经被添加上去了,所以添加请求头很简单,只要添加headers参数即可,headers是一个字典类型,根据需求填入相应的请求头信息就可以轻松的提交各种请求方式了。
3.2 会话维持
说到会话维持,第一想到的就是使用cookies,网页为什么能保持会话,在登陆后不用重新登陆,就是因为cookies保持会话了,所以我们想要会话维持就要在请求头中添加对应的cookies,但是问题来了,如果每次在请求的时候都去添加cookies,这未免也太麻烦了吧,所以requests有一个新的利器-Session对象,利用它,我们可以方便地维护一个会话,而且不用担心cookies的问题,它会帮我们自动处理好。
示例如下:
没有使用Session之前:
import requests
__author__='Evan'
# 第一次访问,并设置cookies
r1=requests.get(url='http://httpbin.org/cookies/set/number/123456789')
print('r1: {}'.format(r1.text))
# 第二次访问
r2=requests.get(url='http://httpbin.org/cookies')
print('r2: {}'.format(r2.text))
打印结果:
r1: {
"cookies": {
"number": "123456789"
}
}
r2: {
"cookies": {}
}
这里我们请求了一个测试网址(http://httpbin.org/cookies/set/number/123456789)
请求这个网址时,可以设置一个cookie,名称叫做number,内容是123456789,
随后又请求了(http://httpbin.org/cookies),此网址可以获取当前的Cookies,但是看打印结果cookies为空,所以使用2次requests是相当于打开两个浏览器,这两次requests的内容是不共享的。
接下来看使用Session的例子:
import requests
__author__='Evan'
# 实例化Session对象
s=requests.Session()
# 第一次访问,并设置cookies
r1=s.get(url='http://httpbin.org/cookies/set/number/123456789')
print('r1: {}'.format(r1.text))
# 第二次访问
r2=s.get(url='http://httpbin.org/cookies')
print('r2: {}'.format(r2.text))
打印结果:
r1: {
"cookies": {
"number": "123456789"
}
}
r2: {
"cookies": {
"number": "123456789"
}
}
成功获取!所以需要登陆某些网站传递登陆信息时就使用Session对象来保持同一个会话,这样就免去了每次要设置cookies的烦琐了。
3.3 代理设置
对于某些网站,在测试的时候请求几次能正常获取内容,但是一旦开始大规模爬取,网站可能会弹出验证码,或者跳转到登陆认证页面,更甚至可能会直接封禁客户端的IP,导致一定时间段内无法访问,那么,为了防止这种情况发生,我们需要设置代理来解决这个问题。
使用proxies参数设置代理:
import requests
__author__='Evan'
# 使用普通格式
proxies={"http": "http://10.10.1.10:3128", "https": "http://10.10.1.10:1080"}
# 使用HTTP Basic Auth格式
proxies={"http": "http://user:password@10.10.1.10:3128"}
# 使用SOCKS协议(需要安装 'requests[socks]' 模块)
proxies={"http": "socks5://user:password@host:port", "https": "socks5://user:password@host:port"}
requests.get('http://httpbin.org/get', proxies=proxies) # 使用代理的GET请求
当然,直接运行这个实例可能不行,因为这些代理IP可能是无效的,这里只讲解proxies的使用格式和方法,具体大家可以去代理IP网站下载免费的代理或者付费的代理试验。
3.4 超时设置
在本机网络状况不好或者服务器网络响应太慢时,我们可能会等待很久的时间才能收到响应,这个时候就可以使用timeout参数,这个时间的计算是从发出请求到服务器响应的时间。
示例如下:
import requests
__author__='Evan'
r=requests.get(url='http://httpbin.org/get', timeout=1)
print(r.text)
打印结果:
Traceback (most recent call last):
File "C:/Evan/my_program/shining_star/trunk/unit_testing/test1.py", line 20, in <module>
r=requests.get(url='http://httpbin.org/get', timeout=1)
File "C:\pycharm_user\venv\lib\site-packages\requests\api.py", line 75, in get
return request('get', url, params=params, **kwargs)
File "C:\pycharm_user\venv\lib\site-packages\requests\api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "C:\pycharm_user\venv\lib\site-packages\requests\sessions.py", line 533, in request
resp=self.send(prep, **send_kwargs)
File "C:\pycharm_user\venv\lib\site-packages\requests\sessions.py", line 646, in send
r=adapter.send(request, **kwargs)
File "C:\pycharm_user\venv\lib\site-packages\requests\adapters.py", line 529, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPConnectionPool(host='httpbin.org', port=80): Read timed out. (read timeout=1)
通过这样的方式,我们可以将超时时间设置为1秒,如果在1秒内没有收到响应,那就抛出异常,还可以加上try-except进行异常处理,防止等待过长而浪费时间,我们还可以直接设置为None,或者不设置直接留空,因为默认也是None,这样的话表示永久等待下去,直到收到服务器响应结果。
3.5 身份认证
在访问某些网站时,我们可能会遇到如下图所示,弹出一个输入框提示身份验证,此时可以使用auth参数添加用户名和密码进行认证。
示例如下:
import requests
__author__='Evan'
r=requests.get('http://localhost:5000', auth=('username', 'password'))
print(r.text)
auth参数是一个元组,该元组第一个参数为用户名,第二个参数为密码,提供这个参数后requests会默认使用HTTPBasicAuth这个类来认证,这样就可以解除认证,继续访问后续页面了。
4. 响应
当我们使用requests请求网页时,会返回一个response,我们就是要解析这个response,才能拿到我们想要的信息,所以接下来先介绍响应是由哪些信息组成的,然后再介绍怎么用requests获取这些信息。
4.1 响应的组成
响应是指服务器返回客户端的结果,可以分为三个部分:(响应状态码、响应头、响应体)
4.1.1 响应状态码
响应状态码表示服务器的响应状态,如200代表服务器正常响应,404代表页面未找到,500代表服务器内部发生错误。在爬虫中,我们可以根据状态码来判断服务器的响应状态然后再进行下一步的处理。
下面列出一些常见的状态码供参考:
200- 【成功】服务器已经成功处理了请求
301- 【永久移动】请求的网页已永久移动到新位置,即永久重定向
302- 【临时移动】请求的网页暂时跳转到其他页面,即暂时重定向
400- 【错误请求】服务器无法解析该请求
401- 【未授权】请求没有进行身份验证或验证未通过
403- 【禁止访问】服务器拒绝此请求
404- 【未找到】服务器找不到请求的网页
408- 【请求超时】服务器请求超时
410- 【已删除】请求的资源已永久删除
500- 【服务器内部错误】服务器遇到错误,无法完成请求
502- 【错误网关】服务器作为网关或代理,从上游服务器收到无效响应
503- 【服务不可用】服务器当前无法使用
504- 【网关超时】服务器作为网关或代理,但是没有及时从上游服务器收到请求
505- 【HTTP版本不支持】服务器不支持请求中所有的HTTP协议版本
4.1.2 响应头
响应头包含了服务器对请求的应答信息,如Content-Type、Server、Set-Cookie等。
下面简要说明一些常用的响应头信息:
4.1.3 响应体
响应体是最重要的内容,响应的正文数据都是在响应体中,比如请求网页时,它的响应体就是网页的HTML代码,请求一张图片时,它的响应体就是图片的二进制数据,在做爬虫时,我们主要通过响应体得到网页的源代码,JSON数据等,然后从中做相应内容的提取。
当然,在我们不使用爬虫时也可以直接看到响应体(也就是网页源代码),所以在开始写爬虫前应先看一遍网页源代码,了解自己要抓取哪些信息,这些信息放在哪个位置等等。
下面介绍一些查看网页源代码的方法:
4.2 响应的获取
在发送请求后,得到的自然就是响应了,上面我们已经介绍了响应是由哪些信息组成的,现在介绍怎么用requests去获取这些信息。
示例如下:
# -*- coding:utf-8 -*-
import requests
__author__='Evan'
r=requests.get(url='http://httpbin.org/get') # 使用GET请求访问
# 获取网页信息
print('请求的URL: {}'.format(r.url)) # 获取当前URL,返回一个字符串
print('响应状态码: {}'.format(r.status_code)) # 获取响应状态码,返回一个整形
print('响应头部信息: {}'.format(r.headers)) # 获取响应头部信息,返回一个字典
print('响应Cookies: {}'.format(r.cookies)) # 获取响应Cookies,返回一个字典
print('访问的历史记录: {}'.format(r.history)) # 获取访问的历史记录,可以查看是否重定向,返回一个列表
print('网页源代码: {}'.format(r.text)) # 获取网页源代码,返回一个字符串
print('网页二进制数据: {}'.format(r.content)) # 获取网页内容的二进制格式,返回一个二进制数据
print('JSON数据: {}'.format(r.json)) # 如果响应信息是JSON数据则调用此方法,返回一个字典
打印结果:
请求的URL: http://httpbin.org/get
响应状态码: 200
响应头部信息: {'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Sat, 21 Dec 2019 13:50:15 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '181', 'Connection': 'keep-alive'}
响应Cookies: <RequestsCookieJar[]>
访问的历史记录: []
网页源代码: {
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.21.0"
},
"origin": "119.123.1.99, 119.123.1.99",
"url": "https://httpbin.org/get"
}
网页二进制数据: b'{\n "args": {}, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.21.0"\n }, \n "origin": "119.123.1.99, 119.123.1.99", \n "url": "https://httpbin.org/get"\n}\n'
JSON数据: <bound method Response.json of <Response [200]>>
原文链接:https://blog.csdn.net/weixin_43750377/article/details/103603834
言
接口测试是我们在测试工作中经常见到的,我们工作中常用到的接口工具有jmeter,postman,soupUI等工具,那么在通过代码做接口测试呢?或者通过代码的方式做接口自动化呢?
requests
requests属于python的第三方库,通常用来发送http和https的请求,既然能向http和https发送请求,那么就能来做接口测试。
安装
pip install requests
requests使用方法
了解requests是如何安装的了,也知道了requests的安装方法了,那么接下来就开始进行实际操作了。
get请求
都知道https请求方式有很多种,如何通过requests来发送get请求呢?这里安静通过模仿百度搜索内容进行发送请求。
其中get方法中存在3个参数:url和params,其中url表示我们请求的地址,params表示请求参数(get方式的请求存在url地址中),headers表示请求头信息内容。
import requests
url='http://www.baidu.com/s'
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
}
params={
"wd": "测试-安静"
}
r=requests.get(url=url, params=params,headers=headers)
print(r)
print(r.url)
if '测试-安静' in r.content.decode('utf-8'):
print('请求成功!')
通过执行结果是成功的。
其中requests的返回内容还有很多种,上面介绍的url,和content只是其中两种。
r.status_code #响应状态码
r.content #字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩
r.headers # 请求头信息
r.json() # Requests中SON
r.url # 获取url
r.encoding # 编码格式
r.cookies # 获取cookie
r.text #字符串方式的响应体
post请求
post请求和get请求类似。post的参数主要有url、data(json)、headers。
url:请求接口地址
data:post请求参数类型
json:post请求参数类型
headers:请求头信息
这里安静通过请求查询天气的接口来模拟post请求。
data请求
import requests
# 登录请求地址
url='http://apis.juhe.cn/simpleWeather/query'
# 请求头
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
}
# body数据
data={
'city': "上海", # 账号
"key": "331eab8f3481f37868378fcdc76cb7cd", # 密码
}
# 发送请求
r=requests.post(url, headers=headers, data=data)
print(r.text)
通过执行发现,已经请求成功,并返回了响应结果。
json请求
import requests
url="http://httpbin.org/post"
# 添加json数据
json={
"username":"AnJing",
"password":"123456"
}
# 通过json方式添加数据
r=requests.post(url,json=json)
print(r.text)
通过执行结果可以看出我们请求的接口类型。
请求HTTPS
现在的网站都是HTTPS的了,所谓的HTTPS就是加密过的网站,在原有的HTTP的基础上加上了SSL。HTTPS的请求基本上都是属于SSL加密的,那么对于这种HTTPS的请求,如果我们通过requests的请求进行访问,会报一个requests.exceptions.SSLError的错误。
对于这种问题,我们可以通过加入参数“verify=False”,requests请求时,verify默认为True,当设置False时,requests请求会进行忽略SSL,从而进行访问HTTPS请求。
import requests
url="https://www.51testing.org/htm/brandpc/PZ.html"
r=requests.get(url, verify=False)
print(r.text)
通过加入参数后,在去执行的时候就不会报SSLerror的错误了。
session
关于session相信大家都不陌生,他和cookies一样使用来表示用户的登录的一种信息,cookies通常保存在客户端的,session保存在服务端上。其中session可以相当于一个虚拟的浏览器,用来保持登录的状态。requests中有单独方法 requests.session() 的方法用来保存登录状态。当然requests中有关于对cookies的登录,我们可以通过cookies加入到请求中,然后用来模拟登录场景。然后再去请求其他页面,可以看看到底我们的会话有没有保存成功。这里通过模拟博客园的场景进行来操作cookies登录。
首先通过Fiddler进行抓取登录前和登录后的cookies值来判断博客园的登录到底是通过什么进行来登录的。
登录前的cookies
登录后的cookies
通过使用fiddler抓取,我们已经找到了登录的cookies内容,然后通过requests中的cookies进行来添加。具体代码:
# coding:utf-8
import requests
import urllib3
urllib3.disable_warnings()
s=requests.session()
s.verify=False
url='https://passport.cnblogs.com/user/signin'
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"
}
r=s.get(url,headers=headers)
cooks={
".Cnblogs.AspNetCore.Cookies":"这里写入抓取到的cookies值",
".CNBlogsCookie":"抓取到的cookies值"
}
c=requests.cookies.RequestsCookieJar()
# 登陆有效的cookies
c.set(".CNBlogsCookie", cooks[".CNBlogsCookie"])
c.set(".Cnblogs.AspNetCore.Cookies", cooks[".Cnblogs.AspNetCore.Cookies"])
# 将cookies值全部添加到session中
s.cookies.update(c)
# 访问后台地址,确定是否登录成功
url1="https://i.cnblogs.com/posts/edit"
r1=s.get(url1)
result=r1.content.decode('utf-8')
if "博客后台 - 博客园" in result:
print("登录成功!")
通过执行发现,我们已经完成了登录后,并通过session的形式进行访问本网站的其他地址一样是保持着登录的状态。
重定向
接口测试中也经常遇到重定向的问题,什么是重定向?就是通过各种方法将各种网络请求重新定个方向转到其它位置。在requests中也有这对重定向的操作allow_redirects其中参数默认是True就是允许重定向,当我们请求的时候,将这个参数设置成False,就能不让其进行重定向。
# coding:utf-8
import requests
url='http://github.com'
# 重定向为False
r=requests.get(url, allow_redirects=False)
print('拒绝重定向请求的状态码:%s'%(r.status_code))
print('拒绝重定向请求地址:%s'%(r.url))
# 重定向为True(默认为True)
r2=requests.get(url)
print('允许重定向请求的状态码:%s'%(r2.status_code))
print('允许重定向请求地址:%s'%(r2.url))
通过执行发现,我们的参数已经设置成功了。在拒绝重定向的时候请求的状态为301,允许重定向的时候为200。
总结
安静简单地介绍了requests中的一些常用方法,这些方法可以帮助我们通过python+requests进行编写关于接口测试的方便的代码。等熟练使用requests后可以进行尝试编写自动化测试代码进行辅助日常测试工作。
请关注+私信回复:“头条”就可以免费拿到软件测试学习资料和面试题库,快速让自己变强!
虫的基本框架是获取HTML页面信息,解析页面信息,保存结果,requests模块是用于第一步获取HTML页面信息; requests库用于爬取HTML页面,提交网络请求,基于urllib,但比urllib更方便;
(一)、发送请求
对应http的不同请求类型,requests库有不同的方法:
1.requests.get():
获取HTML网页的主要方法,对应于HTTP的GET
2.requests.post():
向HTML网页提交POST请求的方法,对应于HTTP的POST
3.requests.head():
获取HTML网页头信息的方法,对应于HTTP的HEAD
4.requests.put():
向HTML网页提交PUT请求,对应于HTTP的PUT
5.requests.patch():
向HTML网页提交局部修改请求,对应于HTTP的PATCH
6.requests.delete():
向HTML页面提交删除请求,对应于HTTP的DELETE
(二)、响应内容
当我们用上述方法向HTML页面发送请求后,会获得一个Response对象;
例如 r=requests.get('https://www.python.org/')
r 就是一个Response对象,我们可以从这个对象中获取我们想要的信息;
Response对象的一些属性有:
(三)、实例
*请认真填写需求信息,我们会在24小时内与您取得联系。