梳理一波requests库的使用方法

python的requests库是我平时用的最多的一个库,无论是做接口测试,还是写爬虫,都离不开它,今天针对它做一个总结

先贴出来官方文档地址:https://requests.readthedocs.io/zh_CN/latest/index.html

1.requests发送get请求和post请求的姿势

get请求的参数可以作为后缀,放在url中;也可以用一个字符串字典的方式传递这些参数

1. 参数在url中
response = requests.get("https://www.baidu.com/?tn=87048150_dg&ch=1")

2.参数独立传递
payload = {'key1': 'value1', 'key2': 'value2'} # 定义参数
response = requests.get(url, params=payload)  # 使用params关键字接收参数

post请求的参数一般是放在请求body中,不会直接暴露在url中,post请求是用data关键字接收参数的

payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post(url, data=payload)

 2.添加headers/查看响应headers

在做爬虫时,有时需要添加一些请求头,在requests中添加请求头也非常方便

headers={
        "authority": "music.163.com",
        "method": "GET",
        "path": "/",
        "scheme": "https",
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "accept-encoding": "gzip,deflate,br",
        "accept-language": "zh-CN,zh;q=0.9",
        "cache-control": "max-age=0",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36"
    }

response = requests.get(url=url, params=data, headers=header)

如果想查看服务返回的请求头信息,可以通过如下方式获取

response.headers

如果想查看发送到服务器的请求头信息(有时候想看下发送的headers是不是和自己写的headers真的一样)

response.request.headers

3.超时处理

在发送请求时,最好设置超时等待时间,避免因为某些原因,程序无休止地等待下去

requests库通过 timeout 参数设定超时等待时间,当超过等待时间,则跳过这个请求(时间单位为 秒)

response = requests.get(url=url, params=data, headers=header,  timeout=10)

 举一个例子,演示下我在爬虫时是如何使用的

下面这段示例代码,是请求谷歌搜索页面,但是因为被墙的原因,是无法请求成功的

1、定义一个循环

2、try语句下表示每次循环都请求一次谷歌搜索,超时时间设置为5s

3、except语句下捕捉Timeout错误,也就是当请求超时时,执行其下的语句,在这里打印了每次请求时的报错信息,这样就不会一直等下去了

import requests

url = "https://www.google.com/?hl=zh_CN"

for t in range(3):
    try:
      r = requests.get(url, timeout=5)
      print("第{}次请求".format(t))
except requests.exceptions.ConnectTimeout as e: print("第{}次请求报错:".format(t), e)

运行结果

 4. 使用cookie或session

有些网站需要校验身份,当我们使用账号密码登录后,浏览器会生成一条或多条cookie信息,后面如果你如果在发送请求时加上这些cookie信息,就不需要再进行登录操作了,可以直接访问(例如postman、jmeter等添加cookie)

发送你的cookies到服务器,可以使用 cookies 参数:

r = requests.get(url, cookies=cookies)

可以用response.cookies来查看响应中的cookie信息,它返回的是CookieJar对象,打印结果如下,可以看到一共包含3段cookie

 打印一下类型

print(type(response.cookies))

 如果你知道cookies中某个cookie的名称,那么可以通过如下方式单独查看这段cookie的值是什么

 print(response.cookies["wordpress_logged_in_b4a55cc11ee65809b7e33131f1779846"])  # 括号中的内容是cookie的name

 举个实际应用的栗子,先通过登录接口获得登录后的cookie,然后后续再发送其他请求时都传入这个cookie,这样就免登录了

response = requests.post(url, data=data, headers=headers) # 假如这个是登录接口,先发起登录
cookies = requests.utils.dict_from_cookiejar(response.cookies) # 调用登录成功后,提取响应中的cookie,并使用requests.utils.dict_from_cookiejar()转成字典格式(因为要使用cookies参数传递cookie信息的话,对应的值需要是字典格式)

后续发送请求时,如下:
r = requests.get(url, params=data, headers=header, cookies=cookies, timeout=10)

 

上面说的方法有一个弊端,每次在发送请求时都要调一下登录接口来获取cookie,所以每次的cookie都不一致,这样就显得啰嗦了,因为没有必要一直获取cookies,只要拿到第一次登陆时的cookies就好了,在cookies过期前可以一直使用它

requests中的会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie,所以就涉及到了session有时在发送一些请求时需要保持登录状态,

s = requests.Session()  # 开启一个会话Session
jar = requests.cookies.RequestsCookieJar()   # 创建一个Cookie Jar对象
jar.set('49BAC005-7D5B-4231-8CEA-1XXX39XEACD67','ckXXXX001')  # 向Cookie Jar对象中添加cookie值
jar.set('JSESSIONID','F4FFF69BXXXX0F0C8DCB4C061C0')
jar.set('JSESSIONIDSSO','9D49C76FDXXXXF5B0F294242B44A')
s.cookies.update(jar)  # 把cookies追加到Session中

r = s.post(url, headers=header, data=data) # 使用session发送请求

 5.请求与响应对象

requests官方文档有这样一段话:

任何时候进行了类似 requests.get() 的调用,你都在做两件主要的事情。

其一,你在构建一个 Request 对象, 该对象将被发送到某个服务器请求或查询一些资源。

其二,一旦 requests 得到一个从服务器返回的响应就会产生一个 Response 对象。该响应对象包含服务器返回的所有信息,也包含你原来创建的 Request 对象。

解释一下

r = requests.get(url, params=data, headers=header, cookies=cookies, timeout=10)

也就是说 执行requests.get()时会先构建一个Request对象

然后服务器响应后会得到一个Response对象,并把它赋给变量r,后面的诸如查看响应状态码、响应内容等都是通过这个Response对象来获得的

下面是常见的访问响应内容的方法

1、查看响应状态码
response.status_code

2、设置编码(避免响应内容乱码,也可以指定编码格式,一般情况下不需要指定,因为它自己会根据响应内容猜测编码)
response.encoding = 'utf-8'

3、查看文本格式响应内容
response.text

4、如何返回json格式的响应内容
Requests 中也有一个内置的 JSON 解码器,助你处理 JSON 数据
response.json()
或者引入json模块,使用
json.loads(response.content)

5、二进制响应内容
以字节的方式访问请求响应体,对于非文本请求,例如爬取视频、图片等
response.content

 6、再看post请求如何发送数据

requests发送get请求不需要多说,因为它的参数形式比较简单,这里需要再提一点关于post请求传参的问题

应该知道post的请求参数有如下几种:表单格式,如form-data、x-www-form-urlencode;json格式字符串,不同的参数形式对应不同的写法

payload = {'key1': 'value1', 'key2': 'value2'}

1、如果想要发送一些编码为表单形式的数据,只需简单地传递一个字典给 data 参数。你的数据字典在发出请求时会自动编码为表单形式:
r
= requests.post(url, data=payload) 2、发送json格式的数据 (1)先在headers中声明Content-Type: "application/json"2)发送请求
r
= requests.post(url, data=json.dumps(payload), headers=headers) 或者 r = requests.post(url, json=payload)

 暂时就这些吧,以后有新的或者说错的地方再补充修改

posted @ 2020-03-19 08:50  我是冰霜  阅读(2531)  评论(0编辑  收藏  举报