梳理一波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)
暂时就这些吧,以后有新的或者说错的地方再补充修改