

Python 中被认为最好用的 HTTP 库 Requests 的使用
source link: https://www.fdevops.com/2022/08/31/python-requests-31158
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

HTTP协议
在开始介绍Requests库和爬虫之前,首先需要先多了解了解HTTP协议,这里就不过多的介绍了,有熟悉HTTP的可以略过,不熟悉的HTTP的可以点击下面地址,去详细的了解以下。
同时推荐一个学习HTTP的书,HTTP权威指南。
Requests介绍及基本使用
Requests是一个简单且优雅的Python HTTP库,相较于Python标准库中的urllib和urllib2的库,Requests更加的便于理解使用。
Requests是Python的第三方库,也是目前公认爬取网页最好的第三方库,使用起来非常简单,简洁。
Requests的安装
# 直接使用pip进行安装即可
pip install requests
Requests安装非常简单,有任何问题,可通过官网查询学习。
https://requests.readthedocs.io/en/master/
检查Requests是否安装成功
>>> import requests
>>> r = requests.get("https://www.fdevops.com")
>>> r.status_code
200
>>> r.encoding = 'utf-8'
>>> r.text
'<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"><meta name="renderer" content="webkit"><meta name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width"><link media="all" href="https://www.fdevops.com/wp-content/cache/autoptimize/css/autoptimize_e29d02f3d2c20b556652ce02cee3d2e7.css" rel="stylesheet" /><title>兰玉磊的技术博客</title><meta name="keywords" content="人工智能...
Requests库的7个主要的方法
方法 | 说明 |
requests.request() | 构造一个请求,支撑以下各方法的基础方法 |
requests.get() | 获取HTML页面的主要方法,对应于HTTP的GET |
requests.head() | 获取HTML页面头信息的方法,对应于HTTP的HEAD |
requests.post() | 向HTML页面提交POST请求的方法,对应于HTTP的POST |
requests.put() | 向HTML页面提交PUT请求的方法,对应于HTTP的PUT |
requests.patch() | 向HTML页面提交局部修改请求,对应于HTTP的PATCH |
requests.delete() | 向HTML页面提交删除请求,对应于HTTP的DELETE |
在Requests库中有两个非常重要的对象,Request和Response。
- Request是请求相关的所有资源
- Response是请求返回的所有资源,在爬虫的过程中占据了非常重要的位置
Requests简单的请求过程
- 首先向指定的url发送GET请求,Requests会构造一个向服务器请求资源的Request对象。
- 当请求送达后,Requests库会接收到服务器返回的一个包含服务器资源的Response对象,这个Response对象就包含了从服务器返回的所有相关资源,包括请求状态,请求的HTML内容等等。
Response对象最常用的5个属性
属性 | 说明 |
r.status_code | HTT请求的返回状态,200表示成功,400表示失败,其他状态值,请查看https://www.fdevops.com/2020/03/14/http-all-code |
r.text | HTTP响应内容的字符串形式,即URL对应的页面内容 |
r.encoding | 从HTTP header中猜测的相应内容编码方式 |
r.apparent_encoding | 从内容中分析出的相应内容编码方式(备选编码方式) |
r.content | HTTP响应内容的二进制形式 |
Requests库的方法介绍
requests.request(method, url, **kwargs)
method: 请求方式,对应get/put/post等7种
url: 获取的页面数据的url链接地址
**kwargs: 控制访问的参数,均为可选项,共13个
requests.request() 参数 method
的请求方式。
r = requests.request("GET", url, **kwargs)
r = requests.request("HEAD", url, **kwargs)
r = requests.request("POST", url, **kwargs)
r = requests.request("PUT", url, **kwargs)
r = requests.request("PATCH", url, **kwargs)
r = requests.request("DELETE", url, **kwargs)
r = requests.request("OPTIONS", url, **kwargs)
equests.request() 中的url
参数就想说了,就是一个你需要爬取的链接地址。
requests.request() 中的**kwargs
参数解析。
params: 字典或字节序列,作为参数增加到url中。
>>> kv = {"a": 1, "b": 2}
>>> r = requests.request("GET", "https://www.fdevops.com", params=kv)
>>> r.url
'https://www.fdevops.com/?a=1&b=2'
data: 字典、字节序列或者文件对象,作为Request对象的内容
>>> kv = {"a": 1, "b": 2}
>>> r = requests.request("POST", "https://www.fdevops.com", data=kv)
>>> body = "测试内容"
>>> r = requests.request("POST", "https://www.fdevops.com", data=body.encode('utf-8'))
>>>
json: JSON格式的数据,作为Request的内容
>>> kv = {"a": 1, "b": 2}
>>> r = requests.request("POST", "https://www.fdevops.com", json=kv)
headers: 字典格式的数据,定制HTTP头数据
>>> hd = {"user-agent": 'Chrome/10'} # 定制headers里的user-agent
>>> r = requests.request("POST", "https://www.fdevops.com", headers=hd)
cookies: 字典或者CookieJar格式,Request中的cookie,从HTTP中解析cookie
auth: 元组,支持HTTP认证功能
files: 字典类型,进行传输文件的时候使用的字段参数
>>> fs = {"file", open("demo.txt", "rb")}
>>> r = requests.request("POST", "https://www.fdevops.com", files=fs)
timeout: 设置超时时间,单位为秒
>>> r = requests.request("GET", "https://www.fdevops.com", timeout=10)
proxies: 字典类型,设置访问代理服务器,可以增加登陆认证,可以有效的隐藏源访问的IP地址,有效的防止对爬虫的逆追踪
>>> pxs = {"http": "http://user:[email protected]:8000",
"https": "https://192.168.1.1:8001"}
>>> r = requests.request("GET", "https://www.fdevops.com", proxies=pxs)
allow_redirects: True/False,默认为True,重定向的开关
stream: True/False,默认为True,对获取的内容是否立即下载的开关
verify: True/False,默认为True,认证SSL证书的开关
cert: 本地SSL证书的路径
requests.get(url, params=None, **kwargs)
url: 获取的页面数据的url链接地址
params: url中的额外参数,字典或者字节流格式,可选参数
**kwargs: 12个控制访问的参数,请参考requests.requests()的**kwargs参数解析
requests.head(url, **kwargs)
url: 获取的页面数据的url链接地址
**kwargs: 13个访问控制参数,请参考requests.requests()的**kwargs参数解析
requests.post(url, data=None, json=None, **kwargs)
url: 获取的页面数据的url链接地址
data: 字典、字节序列或者文件对象,作为Request对象的内容
json: JSON格式的数据,作为Request的内容
**kwargs: 11个访问控制参数,请参考requests.requests()的**kwargs参数解析
requests.put(url, data=None, **kwargs)
url: 获取的页面数据的url链接地址
data: 字典、字节序列或者文件对象,作为Request对象的内容
**kwargs: 12个访问控制参数,请参考requests.requests()的**kwargs参数解析
requests.patch(url, data=None, **kwargs)
url: 获取的页面数据的url链接地址
data: 字典、字节序列或者文件对象,作为Request对象的内容
**kwargs: 12个访问控制参数,请参考requests.requests()的**kwargs参数解析
requests.delete(url, **kwargs)
url: 获取的页面数据的url链接地址
**kwargs: 13个访问控制参数,请参考requests.requests()的**kwargs参数解析
爬取网页的通用代码结构
在我们写爬虫程序的时候,需要按照一个的顺序去处理程序返回的Response对象属性,如下图所示:

通过实际的例子演示一下
>>> import requests
>>> r = requests.get("https://baidu.com")
>>> r.status_code # 状态码
200
>>> r.text # 网页内容
'<!DOCTYPE html>\r\n<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>ç\x99¾åº¦ä¸\x80ä¸\x8bï¼\x8cä½\xa0å°±ç\x9f¥é\x81\x93</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> ...'
>>> r.encoding # 网页编码,若是header中不存在charset字段,则默认为'ISO-8859-1',这种编码格式不支持中文
'ISO-8859-1'
>>> r.apparent_encoding # 根据页面内容得到的编码格式
'utf-8'
>>> r.encoding = r.apparent_encoding # 将编码格式替换成备用的编码格式
>>> r.encoding
'utf-8'
>>> r.text # 用新的编码格式,获取的内容就支持中文了。
'<!DOCTYPE html>\r\n<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> ...'
>>>
通过上面的例子,可以看出如果编码不正确则无法正确的解析数据,而出现乱码的情况。
因为r.encoding
是通过headers
中的charset
来得到的,如果headers
中存在这个字段则是对应的编码格式,如果没有这个字段呢,则默认是ISO-8859-1
,而这种编码格式是无法解析中文,因此会出现中文乱码。
r.apparent_encoding
是根据返回的页面数据来获得的备用编码格式的,因此当出现返回乱码的时候,使用r.apparent_encoding
替换掉r.encoding
即可。
其实严格来说,r.apparent_encoding
比r.encoding
得到的编码格式更加准确,因为r.apparent_encoding
会去分析内容,而r.encoding
不会,仅仅只是通过headers
中`charset`而得到。
编码的简单介绍
- ISO-8859-1 属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母a的编码为0x61=97。很明显,ISO-8859-1编码表示的字符范围很窄,无法表示中文字符。但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用ISO-8859-1编码来表示。而且在很多协议上,默认使用该编码。
- Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。
- UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码。它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部份修改后,便可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。
Requests中的常用异常
我们在爬取网页的过程中,肯定不会是一直一帆风顺的,会出现各种情况,比如已知网络链接异常,防火墙拦截等等,因此在开发爬虫程序的时候,对异常的处理也是非常重要的,需知道每种异常的处理方式。
Requests库支持的6中常用异常
异常 | 说明 |
requests.ConnectionError | 网络连接错误异常,如DNS解析失败,拒绝连接等 |
requests.HTTPError | HTTP错误异常 |
requests.URLRequired | URL缺失异常 |
requests.TooManyRedirects | 超过最大重定向次数,产生重定向异常 |
requests.ConnectTimeout | 连接远程服务器超时异常 |
requests.Timeout | 请求URL超时,产生超时异常 |
Requests中的异常方法
r.raise_for_status() # 如果不是200,产生异常requests.HTTPError
通过一个实际的例子,演示一下:
import requests
def getHTMLText(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status() # 如果状态不是200,则引发HTTPError异常
r.encoding = r.apparent_encoding
return r.text
except Exception as e:
return "产生异常"
if __name__ == '__main__':
url = "https://baidu.com"
print(getHTMLText(url))
可以把上面的实例看成一个爬虫代码的简单结构。
本文为原创文章,未经授权禁止转载本站文章。
原文出处:兰玉磊的个人博客
原文链接:https://www.fdevops.com/2022/08/31/python-requests-31158
版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际」知识共享许可协议进行许可。
</div
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK