美文网首页
web接口自动化--requests库使用

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

作者: D_w | 来源:发表于2021-09-30 09:30 被阅读0次

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

    requests使用

    最简单的GET请求

    发送一个请求分3步:

    • 组装请求: 请求可能包含url,params(url参数),data(请求数据),headers(请求头),cookies等,最少必须有url
    • 发送请求,获取响应:支持get,post等各种方法发送,返回的是一个响应对象
    • 解析响应: 输出响应文本
    # 导入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以字符串格式传输需要遵循以下几点

    • 必须是严格的JSON格式字符串,里面必须用双引号,k-v之间必须有逗号,布尔值必须是小写的true/false等等
    • 不能有中文,直接传字符串不会自动编码
      一般来说,建议将data声明为字典格式(方便数据添加修改),然后再用json.dumps()方法把data转换为合法的JSON字符串格式,如下
    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类型解析

    序列化和反序列化
    • 序列化: 内存对象 -> 文本/文件
    • 反序列化: 文本 -> 内存对象
      对象在HTTP中的传输过程
      HTTP协议是超文本传输协议,是通过文本或二进制进行传输的,所以我们发送的请求要转化成文本进行传输,收到的响应也是文本格式,如果是JSON,一般还需要将文本格式重新转化为对象。
      JSON对象(Python字典) -> 转为文本请求 -> 发送请求-> 服务器收到文本请求 -> 将文本请求转化为对象,获取其中的参数,处理业务-> 返回文本格式的响应 -> 客户端转为对象格式来从响应中取值。
      Python中我们一般提到JSON对象指的是字典
      Python的字典的格式和JSON格式,稍有不同:
    • JSON实际上是字符串
    • 字典中的引号支持单引号和双引号,JSON格式只支持双引号
    • 字典中的True/False首字母大写,JSON格式为true/false
    • 字典中的空值为None, JSON格式为null
    JSON格式操作方法
    • 序列化(字典 -> 文本/文件句柄): json.dumps()/json.dump()
    • 反序列化(文本/文件句柄 -> 字典) : json.loads()/json.load()
    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等等

    请求参数
    • url: 字符串格式,参数也可以直接写到url中
    • params:url参数,字典格式
    • data: 请求数据,字典或字符串格式
    • headers: 请求头,字典格式
    • cookies: 字典格式,可以通过携带cookies绕过登录
    • files: 字典格式,用于混合表单(form-data)中上传文件
    • auth: Basic Auth授权,数组格式 auth=(user,password)
    • timeout: 超时时间(防止请求一直没有响应,最长等待时间),数字格式,单位为秒
    响应解析
    • res.status_code: 响应的HTTP状态码
    • res.reason: 响应的状态码含义
    • req.text:响应的文本格式,按req.encoding解码
    • req.content: 响应的二进制格式
    • req.encoding: 解码格式,可以通过修改req.encoding='utf-8'来解决一部分中文乱码问题
    • req.apparent_encoding:真实编码,由chardet库提供的明显编码
    • req.json(): (注意,有括号),响应的json对象(字典)格式,慎用!如果响应文本不是合法的json文本,或报错
    • req.headers: 响应头
    • req.cookies: 响应的cookieJar对象,可以通过req.cookies.get(key)来获取响应cookies中某个key对应的值
    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方式
    • appid: 系统为合法用户赋予的访问id,固定的字符串,一般经过加密以确保HTTP传输中的安全
    • token: 即令牌,固定或需要动态申请(有一定有效期),一般由用户信息及申请时间计算加密而成,用于验证接口访问的权限
      token与session的区别
    • session是存在服务器的,服务端通过验证客户端的请求所携带的session值在服务会话中是否存在,来验证用户是否合法
    • token: 是按一定算法加密计算出来的,服务端通过解密客户端所携带的token值来验证用户是否合法

    相关文章

      网友评论

          本文标题:web接口自动化--requests库使用

          本文链接:https://www.haomeiwen.com/subject/hxujnltx.html