欢迎关注公众号K的笔记阅读博主更多优质学习内容
requests 模块的导入
request 函数的导入可以直接使用 import requests 来实现,当然,若事先没有安装可以直接在命令行输入 pip install reqeusts 来进行安装。
requests 模块中包含了七个主要的方法,下面将进行一一解析和尝试调用。
requests.get() 函数
requests.get() 函数是一个用于向服务器构造请求资源的 Requests 对象,具体实例如下:
import requests
url = www.baidu.com
r = requests.get(url)
print(r.status_code) # 返回200表示爬取成功
r.encoding = "utf-8" # 转换编码
print(r.text) # 打印对应的HTML文本
print(type(r)) # 应返回 <class 'requests.model.Response'>
print(r.headers) # 应返回{'Cache-Control': 'private (省略)
其中 r 是一个 response 对象,即存储了服务器返回本地的数据,我们对数据的操作即对 r 的操作,response 对象有五个属性,这五个属性是爬虫处理数据的重中之重,其具体含义如下表所示:
属性 | 说明 |
---|---|
r.status_code | HTTP请求的返回状态,202表示连接成功,404表示失败 |
r.text | HTTP相应内容的字符串形式,即 url 对应的页面内容 |
r.encoding | 从HTTP header 中猜测的相应内容编码方式 |
r.apparent_encoding | 从内容中分析出的相应内容编码方式(备选编码方式) |
r.content | HTTP相应内容的二进制形式 |
在我们使用 get 方法从网上获取资源时有基本流程如下:
我们要怎么区分 response 的两种编码方式呢?我们来看一个简单的例子:
import requests
r = requests.get("http://www.baidu.com")
print(r.status_code) # 返回200表示正常运行,可以继续
print(r.text) # 显示的内容很多是乱码看不清编码是什么
print(r.encoding) # 返回 'ISO-8859-1'
print(r.apparent_encoding) # 返回 'utf-8'
r.encoding = 'utf-8'
print(r.text) #返回了正确信息
事实上,r.encoding 中的编码方式是从 HTTP 的 header 中的 charset 字段中获得,如果 HTTP 的 header 中有这个字段,说明我们访问的服务器对其资源的编码是有要求的,编码获得后存在 encoding 中,但若 HTTP 的 header中不含有此字段,将默认编码为 ‘ISO-8859-1’,但此编码并不能解析中文。而 apparent_encoding 则是从 HTTP 内容部分分析出可能的编码形式,原则来说此方法会更准确。
爬取网页的通用代码框架
在实际爬取过程中,requests.get(url) 并不是时时通用的,经常会遇到各种问题,Requests 库支持六种常用的连接异常:
异常 | 说明 |
---|---|
requests.ConnectionError | 网络连接错误异常,如 DNS 查询失败,拒绝连接等 |
requests.HTTPError | HTTP 错误异常 |
requests.URL.Required | URL 缺失异常 |
requests.TooManyRedirects | 超过最大重定向次数,产生重定向异常 |
requests.ConnectTimeout | 连接远程服务器超时异常 |
requests.Timeout | 请求 URL 超时,产生超时异常) |
Response 的异常:
异常 | 说明 |
---|---|
r.raise_for_status() | 如果不是200,产生异常 requests.HTTPError |
这个异常有什么用呢,我们来看一下爬取网页的通用代码框架就一目了然了:
import requests
def geetHTMLText(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
if __name__ == "__main__":
url = "http://www.baidu.com
print(geteHTMLText(url))
HTTP 协议与 Requests 库的主要方法
requests 库有七个主要方法,分别如下:
方法 | 说明 |
---|---|
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 |
为了理解以上方法,我们需要首先了解 HTTP 协议。
HTTP协议
HTTP 协议是超文本传输协议,是一种基于“请求与响应“模式的、无状态的应用层协议,其中无状态指的是第一次请求与第二次请求之间没有直接关联。HTTP 协议采用 URL 作为定位网络资源的标识,URL 格式为
http://host[:port][path],其中 host 是一个合法的 Internet 主机域名或 IP 地址,port 为端口号,缺省端口为80,path 是请求资源的路径。HTTP协议对资源的操作方法如下:
方法 | 说明 |
---|---|
GET | 请求获取 URL 位置的资源 |
HEAD | 请求获取 URL 位置的资源的响应消息报告,即获得该资源的头部信息 |
POST | 请求获取 URL 位置的资源后附加新的数据 |
PUT | 请求获取 URL 位置存储一个资源,覆盖原 URL 位置的资源 |
PATCH | 请求局部更新 URL 位置的资源,即改变该处资源的部分内容 |
DELETE | 请求删除 URL 位置存储的资源 |
我们通过HTTP协议可以对资源进行上述操作,即:
事实上,HTTP 协议通过 URL 做定位,通过上述六个方法对资源进行管理,每个操作都是无状态的。HTTP 协议与 Requests 库的方法是一一对应的,下面以 requests.post() 方法为例说明之:
import requests
payload = {"key1":"value1", "key2":"value2"}
r = requests.post("http://httpbin.org/post", data=payload)
print(r.text)
返回内容:
{...
"form" : {
"key2":"value2",
"key1":"value1"
},
}
这说明用 requests.post() 提交一个键值对时会将数据存储在表单( form ) 下,若提交的是数据,则会存储在 data 下。
Requests 库主要方法解析
request 方法
request 方法的使用规则是:
requests.request(method, url, **kwargs)
其中 method 表示请求方式,具体可填参数有 ‘GET’ , ‘HEAD’, ‘POST’, ‘PUT’, ‘PATCH’, ‘delete’, ‘OPTIONS’,**kwargs 为可选项,有13个参数,下面将进行部分举例:
# params 参数
kv = {"key1":"value1", "key2":"value2"}
r = requests.request('GET', 'http://python123.io/ws', params=kv)
print(r.url)
# http://python123.io/ws?key1=value1&key2=value2
其中"?"后面带的参数可供浏览器进行筛选,再将页面返回。除此之外更常用的是 header 参数:
hd = {'user=agent':'Chrome/10'}
r = requests.request('POST','http://python123.io/ws', headers=hd)
由上述代码可见,我们可以通过修改 headers 的 ‘user-agent’ 部分模拟不同的浏览器进行访问。另外我们也常常需要隐藏自己的 IP 地址来防止爬虫的逆追踪,我们会使用 proxies 可选项:
pxs = {'http' : 'http://user:pass@10.10.10.1:1234'
'https' : 'https://10.10.10.1:4321' }
r = requests.request('GET', 'http://www.baidu.com', proxies=pxs)
其余的可选项还有 data, json, cookies, auth, files, timeout, allow_redirects, stream, verify, cert。
get 方法
requests.get(url, params=None, **kwargs)
其中 params 为 url 中的额外参数,是字典或字节流格式,为可选项。**kwargs 有12个控制访问参数,即 request 方法中除了 params 的其他访问参数,就不一一介绍了。
post 方法
requests.post(url, data=None, json=None, **kwargs)
其中 url 为拟更新页面的 url 链接, data 为字典、字节序列或文件,是 Requests 的内容, json 为 JSON 格式的数据, 是 Requests 的内容,**kwargs 为除了 data 与 json 外的其他控制访问参数。
其他方法
由于其他三个方法使用情况大同小异,直接在下面列出了调用格式:
requests.put(url, data=None, **kwargs)
requests.patch(url, data=None, **kwargs)
requests.delete(url, **kwargs)
事实上我们可以发现,除了 request 方法,其他几个方法都不过是显式定义了 kwargs 中的部分参数。这样定义是因为这几个参数的使用频率更高,因此单独定义出来更方便。
以上内容部分为观看B站叶嵩天老师的爬虫课程笔记,在此将分数期系列文章写出