Python爬虫初级(一)—— Requests 库入门

requests 模块的导入

request 函数的导入可以直接使用 import requests 来实现,当然,若事先没有安装可以直接在命令行输入 pip install reqeusts 来进行安装。
requests 模块中包含了七个主要的方法,下面将进行一一解析和尝试调用。

requests.get() 函数

requests.get() 函数是一个用于向服务器构造请求资源的 Requests 对象,具体实例如下:

1
2
3
4
5
6
7
8
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 方法从网上获取资源时有基本流程如下:

1
2
3
graph LR
A((r.status_code)) -- 返回值为 200 --> B[可以使用 r.text 和 r.encoding 等方法]
A -- 返回值为 404 或其他--> C[某些原因出错将产生异常]

我们要怎么区分 response 的两种编码方式呢?我们来看一个简单的例子:

1
2
3
4
5
6
7
8
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
这个异常有什么用呢,我们来看一下爬取网页的通用代码框架就一目了然了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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协议可以对资源进行上述操作,即:

1
2
3
graph LR 
A[User] -- GET/HEAD --> B((cloud))
B --PUT/POST/PATCH/DELETE-->A

事实上,HTTP 协议通过 URL 做定位,通过上述六个方法对资源进行管理,每个操作都是无状态的。HTTP 协议与 Requests 库的方法是一一对应的,下面以 requests.post() 方法为例说明之:

1
2
3
4
5
import requests

payload = {"key1":"value1", "key2":"value2"}
r = requests.post("http://httpbin.org/post", data=payload)
print(r.text)
1
2
3
4
5
6
7
返回内容:
{...
"form" : {
"key2":"value2",
"key1":"value1"
},
}

这说明用 requests.post() 提交一个键值对时会将数据存储在表单( form ) 下,若提交的是数据,则会存储在 data 下。

Requests 库主要方法解析

request 方法

request 方法的使用规则是:

1
requests.request(method, url, **kwargs)

其中 method 表示请求方式,具体可填参数有 ‘GET’ , ‘HEAD’, ‘POST’, ‘PUT’, ‘PATCH’, ‘delete’, ‘OPTIONS’,**kwargs 为可选项,有13个参数,下面将进行部分举例:

1
2
3
4
5
# 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 参数:

1
2
hd = {'user=agent':'Chrome/10'}
r = requests.request('POST','http://python123.io/ws', headers=hd)

由上述代码可见,我们可以通过修改 headers 的 ‘user-agent’ 部分模拟不同的浏览器进行访问。另外我们也常常需要隐藏自己的 IP 地址来防止爬虫的逆追踪,我们会使用 proxies 可选项:

1
2
3
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 方法

1
requests.get(url, params=None, **kwargs)

其中 params 为 url 中的额外参数,是字典或字节流格式,为可选项。**kwargs 有12个控制访问参数,即 request 方法中除了 params 的其他访问参数,就不一一介绍了。

post 方法

1
requests.post(url, data=None, json=None, **kwargs)

其中 url 为拟更新页面的 url 链接, data 为字典、字节序列或文件,是 Requests 的内容, json 为 JSON 格式的数据, 是 Requests 的内容,**kwargs 为除了 data 与 json 外的其他控制访问参数。

其他方法

由于其他三个方法使用情况大同小异,直接在下面列出了调用格式:

1
2
3
requests.put(url, data=None, **kwargs)
requests.patch(url, data=None, **kwargs)
requests.delete(url, **kwargs)

事实上我们可以发现,除了 request 方法,其他几个方法都不过是显式定义了 kwargs 中的部分参数。这样定义是因为这几个参数的使用频率更高,因此单独定义出来更方便。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2020 chenk
  • 由 帅气的CK本尊 强力驱动
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信