requests库之response响应对象API详解

前言

requests库请求通常用于从特定资源URI中获取响应内容。

每当我们通过Python向指定URI发出请求时,它都会返回一个响应对象。此时此响应对象用于访问某些功能,例如内容,标头等。

response.json()【Requests中内置的JSON解码器】

①如果接口响应体的格式是json格式时,可以使用 response.json() 获取接口响应值的python字典数据类型【相当于将接口返回的json字符串格式的响应体通过python的反序列化转为python字典格式】

注意与postman接口请求工具中的响应结果区分:

②postman工具中请求后的接口响应体是json字符串格式。【与response.json()区分】【可以通过python的反序列化将json字符串转为与r.json()数据类型相同的python字典格式

通常,在接口自动化中,需要将接口的响应的json字符串响应体转为python字典格式【因为不论从Excel或者从Yaml读取的用例都是json字符串格式(与postman中的接口响应值相同)】,然后通过字典方式取值;与response.json()中某个字段值断言。

③注意 response.json() (返回的响应体数据类型为python字典)和 response.text (返回的响应体数据类型为python字符串【会自动根据响应头部的字符编码进行解码】)返回接口响应内容两者的区别:

response.ok

如果status_code小于200,response.ok返回True。

如果status_code大于200,response.ok返回False。

例如:

①token未过期: response.ok 返回Ture

②token已过期: response.ok 返回False

response.url

response.url返回请求和响应的URL。【如果GET请求方法的URL中的查询参数中包含中文,则返回中文被编码后的URL

完成所有重定向后,它将显示返回内容的主URL。

response.raw

 response.raw 返回请求后得到此响应对象的原始响应体对象。【 urllib 的response响应对象,可以使用 response.raw.read() 读取】

response.request.body

 response.request.body 返回此响应的请求对象中的请求体数据。【如果POST请求方法的请求体中包含中文内容,则返回中文被编码后的请求体

【注意】:GET请求得到的response对象中的请求对象的请求体request body为None。

response.request.headers

 response.request.headers 返回此响应的请求对象中的请求头数据字典。

response.request

 response.request返回请求此响应的请求对象。

response.reason

 response.reason返回与响应状态码相对应的描述文本

例如:“确定”为200;“未找到”为404。

# import requests module 
import requests 
  
# Making a get request 
response = requests.get('https://api.github.com/') 
  
# print response 
print(response) 
  
# print the reason 
print(response.reason) 
  
# ping an incorrect url 
response = requests.get('https://geeksforgeeks.org / naveen/') 
  
# print response 
print(response) 
  
# print the reason now 
print(response.reason)

运行结果:

response.encoding

response.encoding 返回用于解码 response.content 的编码方式。【或者理解为将响应内容编码为二进制的编码方式】

response.encoding 是response headers响应头 Content-Type 字段 charset 的值。【 浏览器/postman等接口请求工具将会自动使用该编码方式解码服务端响应的内容】

response.encoding 是从http协议中的response headers响应头中的charset字段中提取的编码方式;

若response headers响应头中没有charset字段,则服务器响应的内容默认为 ISO-8859-1 编码模式【使用此编码方式无法解析中文内容,会造成响应体乱码(解析为乱码数据)】

response.apparent_encoding

response.apparent_encoding 会自动的从服务器接口响应的内容中(响应体)分析内容编码的方式,所以 apparent_encoding 比 encoding 更加准确。当网页或者接口响应内容出现乱码时可以把 apparent_encoding 的编码格式赋值给encoding。

response.content

response.content 以字节为单位返回接口响应的内容。本质上,它是指二进制响应内容。【会自动解码 gzip 和 deflate 压缩】

比如接口的响应是一张图片,我们就需要读取响应体的二进制数据并在本地存为一个图片。

在输出开始时检查 b’,它表示对字节对象的引用。【即表示输出的内容为字节对象】

response.links

response.links 返回标题链接。

检查输出开始处的{},它是否显示标题链接JSON。

response.headers

 response.headers 返回响应头即response headers的数据字典。【该字典的字典键不区分大小写,若键不存在则返回None】

response.request.headers

 response.request.headers 返回请求头即request headers的数据字典。

response.history

response.history 返回包含请求(URL)历史的响应对象列表。

本质上,它以响应列表的形式显示请求如何到达目标。【比如重定向】

# import requests module 
import requests 
  
# Making a get request 
response = requests.get('https://geeksforgeeks.org') 
  
# print response 
print(response) 
  
# print history 
print(response.history)

运行结果:

response.elapsed

response.elapsed返回一个timedelta对象,其中包含从发送请求到响应到达所经过的时间。它通常用于在某个时间点“elapsed”之后停止连接。

response.raise_for_status()

如果在处理过程中发生错误,则 response.raise_for_status()返回 HTTPError 对象。它用于调试请求模块,并且是Python请求的组成部分。

# import requests module 
import requests 
  
# Making a get request 
response = requests.get('https://api.github.com/') 
  
# print response 
print(response) 
  
# print check if an error has occurred 
print(response.raise_for_status()) 
  
# ping an incorrect url 
response = requests.get('https://geeksforgeeks.org / naveen/') 
  
# print check if an error has occurred 
print(response.raise_for_status())

运行结果:

检查Traceback错误,它表明已发生错误以及错误“Invalid URL”和状态代码404。

response.iter_content()

response.iter_content()遍历response.content。 

# import requests module 
import requests 
  
# Making a get request 
response = requests.get('https://geeksforgeeks.org') 
  
# print response 
print(response) 
  
# print iter_content data 
print(response.iter_content()) 
  
# iterates over the list 
for i in response.iter_content():
    print(i)

运行结果:

检查输出开始处的迭代器对象和迭代器,它分别以字节为单位显示迭代器对象和迭代元素。

response.is_permanent_redirect

如果响应是永久重定向的URL,则 response.is_permanent_redirect 返回True,否则返回False。

301重定向是从一个URL到另一个URL的永久重定向。

301将发送的网站访问者和搜索引擎重定向到与他们最初在浏览器中键入或从搜索引擎结果页面选择的URL不同的URL。

# import requests module 
import requests 
  
# Making a get request 
response = requests.get('https://geeksforgeeks.org') 
  
# print response 
print(response) 
  
# print is_permanent_redirect flag 
print(response.is_permanent_redirect)

运行结果:

response.is_redirect

如果响应已重定向,则 response.is_redirect 返回True,否则返回False。

# import requests module 
import requests 
  
# Making a get request 
response = requests.get('https://geeksforgeeks.org') 
  
# print response 
print(response) 
  
# print is_redirect Flag 
print(response.is_redirect)

运行结果:

response.close()

close()来自响应对象。 response.close() 表示关闭与服务器的连接。

# import requests module 
import requests 
  
# Making a put request 
response = requests.get('https://api.github.com') 
  
# print response 
print(response) 
  
# closing the connection 
response.close() 
  
# Check if this gets execeuted 
print("Connection Closed")

运行结果:

response.request.hooks

requests提供了hook机制,让我们能够在请求得到响应之后去做一些自定义的操作;比如打印某些信息、修改响应内容等。

举例:

import requests


# 钩子函数1
def print_url(r, *args, **kwargs):
    print("raw_url " + r.url)


# 钩子函数2
def change_url(r, *args, **kwargs):
    r.url = 'http://change.url'
    print("changed_url " + r.url)
    return r  # 其实没有这句话,也可以修改r.url,因为r是response对象而非普通数值,但requests官方似乎误认为回调函数一定要有return才能替换传入的数据


# tips: http://httpbin.org能够用于测试http请求和响应
url = 'http://httpbin.org/cookies'
response = requests.get(url, hooks=dict(response=[print_url, change_url]))
print("result_url " + response.url)

运行结果:

解释:

在上述例子中:

①定义了两个钩子函数,分别用来打印response对象中的url(print_url)和修改response对象中的url(change_url)。

②通过参数 hooks=dict(response=[print_url, change_url])调用。其中response是钩子的类型

③从运行结果中,可以看出钩子函数1(print_url)和钩子函数2(change_url)被顺序执行了,且达到了篡改响应结果的目的。

④在上述例子中,只在requests方法级别调用了一次hook,如果想要每个请求都使用hook呢?可以在requests的session对象中添加hook来让该session对象发出去的请求均带有hook,例如:

s = requests.Session()

s.hooks.update({"response": [print_url, change_url]})

 

posted @ 2021-10-22 11:30  习久性成  阅读(8492)  评论(0编辑  收藏  举报