requests模块
1、为什么要重点学习requests模块,而不是urllib
-
企业中用的最多的就是requests
-
requests的底层实现就是urllib
-
requests在python2 和python3中通用,方法完全一样
-
requests简单易用
2、requests的作用与安装
作用:发送网络请求,返回响应数据
安装
pip install requests
如果安装速度慢的话可以改用国内的源进行下载安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
3、requests模块发送简单的get请求、获取响应
需求:通过requests向百度首页发送请求,获取百度首页的数据
import requests
# 目标url
url = 'https://www.baidu.com'
# 向目标url发送get请求
response = requests.get(url)
# 打印响应内容
print(response.text)
response的常用属性:
-
response.text响应体 str类型 -
response.encoding从HTTP header中猜测的响应内容的编码方式 -
respones.content响应体 bytes类型 -
response.status_code响应状态码 -
response.request.headers响应对应的请求头 -
response.headers响应头 -
response.request.cookies响应对应请求的cookie -
response.cookies响应的cookie(经过了set-cookie动作) -
response.url获取访问的url -
response.json()获取json数据 得到内容为字典 (如果接口响应体的格式是json格式时) -
response.ok如果status_code小于200,response.ok返回True。
如果status_code大于200,response.ok返回False。
思考:text是response的属性还是方法呢?
-
一般来说名词,往往都是对象的属性,对应的动词是对象的方法
3.1 response.text 和response.content的区别
-
response.text-
类型:str
- 如果希望获取的是字符串,使用此方法。
-
解码类型: requests模块自动根据HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
-
如何修改编码方式:
response.encoding="gbk/UTF-8"
-
-
response.content-
类型:bytes
- 如果希望获取的是图片等二进制内容,使用此方法。
-
解码类型: 没有指定
-
如何修改编码方式:
response.content.deocde("utf8")
-
获取网页源码的通用方式:
-
response.content.decode() -
response.content.decode("UTF-8") -
response.text
以上三种方法从前往后尝试,能够100%的解决所有网页解码的问题
所以:更推荐使用response.content.deocde()的方式获取响应的html页面
3.2 练习:把网络上的图片保存到本地
我们来把
www.baidu.com的图片保存到本地
思考:
-
以什么方式打开文件
-
保存什么格式的内容
分析:
-
利用requests模块发送请求获取响应
-
以2进制写入的方式打开文件,并将response响应的二进制内容写入
import requests
# 图片的url
url = 'https://www.baidu.com/img/bd_logo1.png'
# 响应本身就是一个图片,并且是二进制类型
response = requests.get(url)
# print(response.content)
# 以二进制+写入的方式打开文件
with open('baidu.png', 'wb') as f:
# 写入response.content bytes二进制类型
f.write(response.content)
4、发送带header的请求
我们先写一个获取百度首页的代码
import requests
url = 'https://www.baidu.com'
response = requests.get(url)
print(response.content)
# 打印响应对应请求的请求头信息
print(response.request.headers)
4.1 思考
对比浏览器上百度首页的网页源码和代码中的百度首页的源码,有什么不同?
代码中的百度首页的源码非常少,为什么?
4.2 为什么请求需要带上header?
模拟浏览器,欺骗服务器,获取和浏览器一致的内容
4.3 header的形式:字典
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
4.4 用法
requests.get(url, headers=headers)
4.5 完整的代码
import requests
url = 'https://www.baidu.com'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
# 在请求头中带上User-Agent,模拟浏览器发送请求
response = requests.get(url, headers=headers)
# print(response.content)
# 打印请求头信息
print(response.request.headers)
5、发送带参数的请求
我们在使用百度搜索的时候经常发现url地址中会有一个
?,那么该问号后边的就是请求参数,又叫做查询字符串
5.1 什么叫做请求参数:
例1: http://www.webkaka.com/tutorial/server/2015/021013/
例2:https://www.baidu.com/s?wd=python&a=c
例1中没有请求参数!例2中?后边的就是请求参数
5.2 请求参数的形式:字典
kw = {'wd':'长城'}
5.3 请求参数的用法
requests.get(url,params=kw)
5.4 关于参数的注意点
在url地址中, 很多参数是没有用的,比如百度搜索的url地址,其中参数只有一个字段有用,其他的都可以删除 如何确定那些请求参数有用或者没用:挨个尝试! 对应的,在后续的爬虫中,越到很多参数的url地址,都可以尝试删除参数
5.5 两种方式:发送带参数的请求
-
对
https://www.baidu.com/s?wd=python发起请求可以使用requests.get(url, params=kw)的方式# 方式一:利用params参数发送带参数的请求 import requests headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"} # 这是目标url # url = 'https://www.baidu.com/s?wd=python' # 最后有没有问号结果都一样 url = 'https://www.baidu.com/s?' # 请求参数是一个字典 即wd=python kw = {'wd': 'python'} # 带上请求参数发起请求,获取响应 response = requests.get(url, headers=headers, params=kw) # 当有多个请求参数时,requests接收的params参数为多个键值对的字典,比如 '?wd=python&a=c'-->{'wd': 'python', 'a': 'c'} print(response.content) -
也可以直接对
https://www.baidu.com/s?wd=python完整的url直接发送请求,不使用params参数# 方式二:直接发送带参数的url的请求 import requests headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"} url = 'https://www.baidu.com/s?wd=python' # kw = {'wd': 'python'} # url中包含了请求参数,所以此时无需params response = requests.get(url, headers=headers)
6、使用requests发送POST请求
思考:哪些地方我们会用到POST请求?
-
登录注册( POST 比 GET 更安全)
-
需要传输大文本内容的时候( POST 请求对数据长度没有要求)
所以同样的,我们的爬虫也需要在这两个地方回去模拟浏览器发送post请求
6.1 requests发送post请求语法:
-
用法:
response = requests.post("http://www.baidu.com/", data = data, headers=headers) -
data 的形式:字典
6.2 POST请求练习
下面面我们通过金山翻译的例子看看post请求如何使用:
思路分析
1.抓包确定请求的url地址

2.确定请求的参数

3.确定返回数据的位置

4.模拟浏览器获取数据
import requests
import json
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
url = 'https://ifanyi.iciba.com/index.php?c=trans&m=fy&client=6&auth_user=key_ciba&sign=99730f3bf66b2582'
data = {
'from': 'zh',
'to': 'en',
'q': 'lucky 是一个帅气的老师'
}
res = requests.post(url, headers=headers, data=data)
# print(res.status_code)
# 返回的是json字符串 需要在进行转换为字典
data = json.loads(res.content.decode('UTF-8'))
# print(type(data))
print(data)
print(data['content']['out'])
使用request获取的resposne对象,具有cookies属性,能够获取对方服务器设置在本地的cookie,但是如何使用这些cookie呢?
7.1 方法介绍
-
response.cookies是CookieJar类型
-
使用requests.utils.dict_from_cookiejar,能够实现把cookiejar对象转化为字典
7.2 方法展示
import requests
url = "http://www.baidu.com"
#发送请求,获取resposne
response = requests.get(url)
print(type(response.cookies))
#使用方法从cookiejar中提取数据 等同于 dict(response.cookies)
cookies = requests.utils.dict_from_cookiejar(response.cookies)
print(cookies)
输出为:
<class 'requests.cookies.RequestsCookieJar'>
{'BDORZ': '27315'}
注意:
在前面的requests的session类中,我们不需要处理cookie的任何细节,如果有需要,我们可以使用上述方法来解决
8、requests处理证书错误
经常我们在网上冲浪时,经常能够看到下面的提示:

出现这个问题的原因是:ssl的证书不安全导致
8.1 代码中发起请求的效果
那么如果在代码中请求会怎么样呢?
import requests
url = "https://www.12306.cn/mormhweb/"
response = requests.get(url)
返回证书错误,如下:
ssl.CertificateError ...
8.2 解决方案
为了在代码中能够正常的请求,我们修改添加一个参数
import requests
url = "https://www.12306.cn/mormhweb/"
response = requests.get(url,verify=False)
9、超时参数的使用
在平时网上冲浪的过程中,我们经常会遇到网络波动,这个时候,一个请求等了很久可能任然没有结果
在爬虫中,一个请求很久没有结果,就会让整个项目的效率变得非常低,这个时候我们就需要对请求进行强制要求,让他必须在特定的时间内返回结果,否则就报错
9.1 超时参数使用方法如下:
response = requests.get(url,timeout=3)
通过添加timeout参数,能够保证在3秒钟内返回响应,否则会报错
注意:
这个方法还能够拿来检测代理ip的质量,如果一个代理ip在很长时间没有响应,那么添加超时之后也会报错,对应的这个ip就可以从代理ip池中删除
10、retrying模块的使用
使用超时参数能够加快我们整体的请求速度,但是在正常的网页浏览过成功,如果发生速度很慢的情况,我们会做的选择是刷新页面,那么在代码中,我们是否也可以刷新请求呢?
对应的,retrying模块就可以帮助我们解决
10.1 retrying模块的使用
retrying模块的地址:https://pypi.org/project/retrying/
pip install retrying
retrying 模块的使用
-
使用retrying模块提供的retry模块
-
通过装饰器的方式使用,让被装饰的函数反复执行
-
retry中可以传入参数
stop_max_attempt_number,让函数报错后继续重新执行,达到最大执行次数的上限,如果每次都报错,整个函数报错,如果中间有一个成功,程序继续往后执行
10.2 retrying和requests的简单封装
实现一个发送请求的函数,每次爬虫中直接调用该函数即可实现发送请求,在其中
-
使用timeout实现超时报错
-
使用retrying模块实现重试
代码参考:
# parse.py
import requests
from retrying import retry
headers = {}
#最大重试3次,3次全部报错,才会报错
@retry(stop_max_attempt_number=3)
def _parse_url(url)
#超时的时候回报错并重试
response = requests.get(url, headers=headers, timeout=3)
#状态码不是200,也会报错并重试
assert response.status_code == 200
return response
def parse_url(url)
try: #进行异常捕获
response = _parse_url(url)
except Exception as e:
print(e)
#报错返回None
response = None
return response
11、扩展
**kwargs:控制访问的参数,均为可选项
-
params: 字典或字节序列,作为参数增加到url中
-
data:字典,字节序列或文件对象,作为Request的内容
-
headers: 字典, HTTP定制头
-
timeout: 设定超时时间,秒为单位
-
proxies [ˈprɑksiz] : 字典类型,设定访问代理服务器,可以增加登录认证
-
verify[ˈverəti] : True/False默认Ture,认证ssl证书开关
浙公网安备 33010602011771号