前言
关于爬虫的教程网络上满天飞,我想,这应该是由于它极大地有利于信息资源的收集和分析。简单来说,在Python中,有许多大佬编写的基本库,我们可以使用这些库中的许多函数和方法,发送HTTP请求。
怎样通过 urllib库 发送 HTTP 请求?
什么是 urllib? 字面意思,即关于url的一个lib。作为一个Python的内置的HTTP请求库,urlllib提供了一些可以通过URL访问各种信息资源的类和函数。
urllib库主要由四个模块组成:
urllib.request
打开和读取 URLurllib.error
包含urllib.request
抛出的异常urllib.parse
用于解析 URLurllib.robotparser
用于解析robots.txt
文件
1. 使用urllib.parse
解析URL
- 使用
urlparse()
分段URL事实上,在1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29# 导入工具包
from urllib.parse import urlparse
# 使用urlparse()函数解析URL
result = urlparse('https://docs.python.org/3/library/urllib.parse.html#url-parsing')
# 输出解析结果
print(type(result))
print(result)
```
在这里,我们用`urlparse()`函数构建了一个**实例对象**(ParseResult类型),并将其赋值给`result`,以便调用。
事实上,**ParseResult类型**对象包含6个部分:
- **scheme**,代表**协议**,通常在"://"前面,这里即`http`
- **netloc**,代表**域名**,通常在第一个"/"前面,这里即`docs.python.org:80`
- **path**,代表**访问路径**,通常在域名之后,这里即`/3/library/urllib.parse.html`
- **params**,代表**参数**,通常在"?"之前,这里不存在
- **query**,代表**查询条件**,通常在"?"之后,这里也不存在
- **fragment**,代表**瞄点**,通常在"#"之后,用于直接定位页面内部的下拉位置,这里即`url-parsing`
- 使用`urlunparse()`构造URL
```python
# 导入工具包
from urllib.parse import urlunparse
# 构建列表行参数
data = ['http','www.baidu.com','index.html','user','a=6','comment']
# 构造完整的URL,并打印
print(urlunparse(data))urllib.parse
中,解析URL的方法不仅有urlparse()
函数,还有urlsplit()
等;构造URL的方法不仅有urlunparse()
函数,还有urlunsplit
和urlencode()
等。
2. 使用urllib.request
打开 URL,模拟发送请求
使用
urllib.request.urlopen
函数发送HTTP请求,构造对象1
2
3
4
5
6
7
8# 导入工具包
import urllib.request
# 使用`urlopen`函数发送HTTP请求
response = urllib.request.urlopen('https://www.baidu.com')
# 打印网页源代码
print(response.read().decode('utf-8'))urllib.request.urlopen
函数构造一个接受请求的实例对象(HTTPResponse类型),并将其赋值给response
变量,以便之后使用。read()
方法可以得到返回的网页内容。事实上,HTTPResponse类型的对象,不仅可以调用read()
和getheaders()
等方法,还可以调用status
和msg
等属性来查看请求发送后返回的一系列信息。通过
Request
类灵活配置参数,构建请求信息对象1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# 导入工具包
import urllib.request
# 设置url、headers等参数
url = 'http://httpbin.org/post'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
'Host':'httpbin.org'
}
# 集合请求参数,独立成对象
req = request.Request(url=url,headers=headers,method='POST')
# 发送HTTP请求
response = request.urlopen(req)
# 打印
print(response.read().decode('utf-8'))这里我们依然使用
urlopen()
方法来发送HTTP请求,但是传递的不再是单纯的URL,而是一个Request
类型的对象。通过集合各种参数,将其独立成一个对象,可以更加丰富和灵活地配置参数。这里的
headers
即为请求头,method
即为请求方法使用
Handler
处理器进行高级操作(以Cookies处理为例)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# 导入工具包
import urllib.request
import http.cookiejar
# 声明一个CooieJar对象
cookie = http.cookiejar.Cookiejar()
# 构建一个专门处理Cookies的对象
handler = urllib.request.HTTPCookieProcessor(cookie)
# 构建一个Opener对象
opener = urllib.request.build_opener(handler)
# 通过open()方法打开链接
response = opener.open('https://www.baidu.com')
# 查看每条Cookie的名称和值
for item in cookie:
print(item.name+'='+item.value)HTTPCookieProcessor
是urllib.request
模块里用于处理Cookie的一个类。值得注意的是这里打开链接的不再是request.urlopen()
函数,而是用Opener对象的open()
方法来发出请求。
3. 使用urllib.error
捕捉请求错误,进行异常处理
使用
URLError
类捕捉URL异常1
2
3
4
5
6
7
8
9# 导入工具包
from urllib import request, error
# 使用try块,捕捉可能的异常
try:
response = request.urlopen('https://baidu.com')
# 将异常对象赋值给变量e
except error.URLError as e:
print(e.reason)在这里如果发生网页不存在等请求异常,我们就可以通过
URLError
捕捉异常,从而避免程序的异常终止使用
HTTPError
类捕捉HTTP请求错误1
2
3
4
5
6
7
8# 导入工具包
from urllib import request, error
# 用try块捕捉可能的错误
try:
response = request.urlopen('http://baidu.com')
except error.HttpError as e:
print(e.reason, e.code, e.headers, seq='\n')
参考资料
urllib - URL handling modules. Python官方文档
Python3网络爬虫开发实战教程. 崔庆才