web接口自动化--requests库使用

2021-09-30  本文已影响0人  D_w

转自 临渊的博客 https://www.cnblogs.com/superhin/p/10338930.html
在接口自动化中使用requests库发送http请求更简单,支持自动编码解码,会话保持,长连等。

requests使用

最简单的GET请求

发送一个请求分3步:

# 导入requests包
import requests 

# 1. 组装请求
url = "http://httpbin.org/get"  # 这里只有url,字符串格式
# 2. 发送请求,获取响应
res = requests.get(url) # res即返回的响应对象
# 3. 解析响应
print(res.text)  # 输出响应的文本
带参数的GET请求
import requests 

url = "http://www.tuling123.com/openapi/api?key=ec961279f453459b9248f0aeb6600bbe&info=你好"  # 参数可以写到url里
res = requests.get(url=url) # 第一个url指get方法的参数,第二个url指上一行我们定义的接口地址
print(res.text)  

import requests 

url = "http://www.tuling123.com/openapi/api"
params = {"key":"ec961279f453459b9248f0aeb6600bbe","info":"你好"} # 字典格式,单独提出来,方便参数的添加修改等操作
res = requests.get(url=url, params=params)   # 这里的params只接受字典类型
print(res.text)  

get方法的params只接受字典类型

传统表单类POST请求(x-www-form-urlencoded)
import requests 

url = "http://httpbin.org/post"
data = {"name": "hanzhichao", "age": 18} # Post请求发送的数据,字典格式
res = requests.post(url=url, data=data) # 这里使用post方法,参数和get方法一样
print(res.text)  
JSON类型的POST请求(application/json)json可以理解为字典的字符串型
import requests 

url = "http://httpbin.org/post"
data = '''{
        "name": "hanzhichao",
        "age": 18
        }''' # 多行文本, 字符串格式,也可以单行(注意外层有引号,为字符串) data = '{"name": "hanzhichao", "age": 18}'
res = requests.post(url=url, data=data) #  data支持字典或字符串
print(res.text)  

post方法的data参数支持字典和字符串型(json)
如果data以字符串格式传输需要遵循以下几点

import requests 
import json # 使用到JSON中的方法,需要提前导入

url = "http://httpbin.org/post"
data = {
        "name": "hanzhichao",
        "age": 18
        }  # 字典格式,方便添加
headers = {"Content-Type":"application/json"} # 严格来说,我们需要在请求头里声明我们发送的格式
res = requests.post(url=url, data=json.dumps(data), headers=headers) #  将字典格式的data变量转换为合法的JSON字符串传给post的data参数
print(res.text)  

import requests 

url = "http://openapi.tuling123.com/openapi/api/v2"
data = {
    "reqType":0,
    "perception": {
        "inputText": {
            "text": "附近的酒店"
        },
        "inputImage": {
            "url": "imageUrl"
        },
        "selfInfo": {
            "location": {
                "city": "北京",
                "province": "北京",
                "street": "信息路"
            }
        }
    },
    "userInfo": {
        "apiKey": "ec961279f453459b9248f0aeb6600bbe",
        "userId": "206379"
    }
} 
res = requests.post(url=url, json=data) # JSON格式的请求,将数据赋给json参数
print(res.text)  

JSON类型解析

序列化和反序列化
JSON格式操作方法
import json # 需要导入JSON包

data = {'name': '张三', 'password': '123456', "male": True, "money": None} # 字典格式
str_data = json.dumps(data) # 序列化,转化为合法的JSON文本(方便HTTP传输)
print(str_data)
----------------------输出------------------------
{"name": "\u5f20\u4e09", "password": "123456", "male": true, "money": null}

json.dumps()支持将json文本格式化输出

import requests 
import json

res = requests.post("http://www.tuling123.com/openapi/api?key=ec961279f453459b9248f0aeb6600bbe&info=怎么又是你") 
print(res.text) # 输出为一行文本
res_dict = res.json() # 将响应转为json对象(字典)等同于`json.loads(res.text)`
print(json.dumps(res_dict, indent=2, sort_keys=True, ensure_ascii=False)) # 重新转为文本
----------------------输出------------------------
{"code":100000,"text":"我才要说怎么又是你"}  # res.text,有些接口中文会返回为\u..
{
  "code": 100000,
  "text": "我才要说怎么又是你"  # 树状格式,比较清晰,显示中文
}

json.dumps中的参数:indent: 缩进空格数,indent=0输出为一行;sork_keys=True: 将json结果的key按ascii码排序;ensure_ascii=Fasle: 不确保ascii码,如果返回格式为utf-8包含中文,不转化为\u...。
反序列化

import json

res_text = '{"name": "\u5f20\u4e09", "password": "123456", "male": true, "money": null}'  # JSON文本格式的响应信息,注意这里最外层有''
res_dict = json.loads(res_text) # 转化为字典 
print(res_dict['name'])  # 方便获取其中的参数值

文件的序列号和反序列化
1.序列化:字典 -> 文件句柄

import json

res_dict = {'name': '张三', 'password': '123456', "male": True, "money": None} # 字典格式
f = open("demo1.json","w")
json.dump(res_dict, f)

查看同级目录,增加了一个demo1.json文件,内容为:

{"name": "\u5f20\u4e09", "password": "123456", "male": true, "money": null}

2.反序列化: 文件句柄 -> 字典
在项目中(和下面脚本文件同一路径下)新建demo2.json文件,内容如下,保存

{
  "name": "张三",
  "password": "123456",
  "male": true,
  "money": null
}

新建Python文件

import json

f = open("demo2.JSON","r", encoding="utf-8")  # 文件中有中文需要指定编码
f_dict = json.load(f) # 反序列化将文件句柄转化为字典
print(f_dict['name']) # 读取其中参数
f.close()

requests库详解

请求方法

request(),get(),options(),head(),post(),put(),patch(),delete(),requests.session(): 用于保持会话(session),除了requests.session()外,其他请求方法的参数都差不多,都包含url,params, data, headers, cookies, files, auth, timeout等等

请求参数
响应解析
import requests 

res = requests.get("https://www.baidu.com") 
print(res.status_code, res.reason) # 200 OK
print(res.text) # 文本格式,有乱码
print(res.content) # 二进制格式
print(res.encoding) # 查看解码格式 ISO-8859-1
print(res.apparent_encoding) # utf-8
res.encoding='utf-8' # 手动设置解码格式为utf-8
print(res.text) # 乱码问题被解决
print(res.cookies.items()) # cookies中的所有的项 [('BDORZ', '27315')]
print(res.cookies.get("BDORZ")) # 获取cookies中BDORZ所对应的值 27315

带安全认证的请求

需要登录的请求(Cookie/Session认证)

1.使用会话保持

import requests

s = requests.session() # 新建一个会话
s.post(url="https://demo.fastadmin.net/admin/index/login.html",data={"username":"admin","password":"123456"}) # 发送登录请求
res = s.get("https://demo.fastadmin.net/admin/dashboard?ref=addtabs") # 使用同一个会话发送get请求,可以保持登录状态
print(res.text)

2.抓取cookies

import requests

url = "https://demo.fastadmin.net/admin/dashboard?ref=addtabs"
cookies = {"PHPSESSID":"9bf6b19ddb09938cf73d55a094b36726"}   # 登录后在Headers的cookie中获得
res = requests.get(url=url, cookies=cookies) # 携带cookies发送请求
print(res.text)

两种方式的对比

  1. 使用session方式:每次都要发送两次请求,效率较低
  2. 使用携带cookies方式:需要手动抓包,提取组装,cookies中是session有一定有效期,过期之后要重新抓取和更换cookies
  3. 如果很多或所有请求都需要登录,可以发一次请求,保持该session为全局变量,其他接口都使用该session发送请求(同样要注意登录过期时间)
appid或token方式
上一篇下一篇

猜你喜欢

热点阅读