目录
[2.1 urllib.request](#2.1 urllib.request)
[2.2.1 urllib.request.urlopen()](#2.2.1 urllib.request.urlopen())
[2.1.2 urllib.request.Request()](#2.1.2 urllib.request.Request())
[2.1.3 urllib.request.urlencode()](#2.1.3 urllib.request.urlencode())
[2.2 urllib.parse](#2.2 urllib.parse)
[2.2.1 urllib.parse.urlparse()](#2.2.1 urllib.parse.urlparse())
[2.2.2 urllib.parse.urlunparse()](#2.2.2 urllib.parse.urlunparse())
[2.2.3 urllib.parse.urljoin()](#2.2.3 urllib.parse.urljoin())
[2.2.4 urllib.parse.urlencode()](#2.2.4 urllib.parse.urlencode())
[2.2.5 urllib.parse.parse_qs()](#2.2.5 urllib.parse.parse_qs())
[2.2.6 urllib.parse.quote()](#2.2.6 urllib.parse.quote())
[2.2.7 urllib.parse.unquote()](#2.2.7 urllib.parse.unquote())
[2.3 urllib.error](#2.3 urllib.error)
[2.4 urllib.robotparser](#2.4 urllib.robotparser)
[2.4.1 set_url()](#2.4.1 set_url())
[2.4.2 read()](#2.4.2 read())
[2.4.3 can_fetch()](#2.4.3 can_fetch())
一、介绍urllib库
urllib是Python标准库中用于处理URL(统一资源定位器)的模块之一。它提供了一组用于发送HTTP(超文本传输协议)请求的函数,以及用于处理URL编码和解码的工具函数。它可以实现以下功能:
- 打开URL并读取响应内容
- 发送POST、GET等HTTP请求
- 设置请求头信息
- 处理URL编码和解码
- 处理Cookie
- 处理代理服务器
- 设置超时时间
- 处理重定向
- 处理HTTPS请求
二、urllib库的核心模块
urllib库包含4个模块,分别是:urllib.request、urllib.parse、urllib.error和urllib.robotparser。
2.1 urllib.request
**urllib.request
**是 Python 内置的 HTTP 请求库,用于发送 HTTP 请求并获取服务器响应。它提供了一系列的函数和类,用于构建 HTTP 请求、处理响应和管理请求的上下文。
以下是 urllib.request中常用的一些函数和类:
- urlopen(url, data=None, [timeout, ]*):发送一个 HTTP GET 请求,并返回一个类似文件的对象来访问响应。可以接受一个字符串形式的 URL,也可以接受一个 Request 对象。
- Request(url, data=None, headers={}, method=None):用于构建 HTTP 请求的对象。可以指定请求的 URL、发送的数据、请求头和请求方法。
- urlencode(query, doseq=False, safe='', encoding=None, errors=None):将一个字典或包含键值对的序列转换为 URL 编码的查询字符串。
- urlretrieve(url, filename=None, reporthook=None, data=None):下载并保存一个远程文件到本地。
- URLopener:提供了更高级别的接口来发送 HTTP 请求。可以通过继承该类来添加更多自定义的行为。
使用 urllib.request
发送 HTTP 请求的一般流程如下:
- 构建
Request
对象,指定请求的 URL、发送的数据、请求头和请求方法(可选)。 - 调用
urlopen()
方法发送请求,获取服务器响应。 - 通过读取返回的响应对象来获取服务器响应的内容。
以下是一个简单的示例,演示如何使用 urllib.request 发送 HTTP 请求:
python
import urllib.request
# 构建 Request 对象
req = urllib.request.Request('https://www.example.com/')
# 发送请求并获取响应
response = urllib.request.urlopen(req)
# 读取响应内容
content = response.read()
# 打印响应内容
print(content)
2.2.1 urllib.request.urlopen()
urllib.request.urlopen()函数是Python中用于打开URL的函数。它接受一个URL作为参数,并返回一个类似文件对象的response对象,可以通过该对象访问和处理URL返回的数据。
函数的基本语法如下:
python
response = urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
参数说明:
- url: 要打开的URL。
- data: 要发送的数据。默认为None。
- timeout: 请求超时时间。单位为秒。
- cafile, capath, cadefault, context: 安全相关参数,用于HTTPS请求的SSL验证。
urlopen()函数会自动处理HTTP和HTTPS协议。返回的response对象有以下常用方法:
- read(size=-1): 读取并返回response的内容。可选参数size指定读取的字节数,默认为-1,表示读取全部内容。
- geturl(): 返回请求的URL。
- info(): 返回response的headers信息。
- getcode(): 返回response的HTTP状态码。
python
import urllib.request
response = urllib.request.urlopen('http://www.example.com')
html = response.read().decode('utf-8')
print(html)
2.1.2 urllib.request.Request()
urllib.request.Request()是Python内置的一个类,用于构建HTTP请求。
参数如下:
- url:请求的url地址。
- data:要发送的数据,默认为None。
- headers:请求头信息,默认为None。
- method:请求方法,默认为GET。
该类的实例化对象作为urlopen()函数的参数,用于发送HTTP请求。下面是一个例子:
python
import urllib.request
url = 'https://www.example.com'
req = urllib.request.Request(url) # 创建一个Request对象
response = urllib.request.urlopen(req)
data = response.read()
print(data)
在这个例子中,我们首先创建了一个Request对象,并指定了请求的url地址。然后,使用urlopen()函数,将Request对象作为参数发送HTTP请求。最后,使用read()方法读取响应数据并打印出来。
2.1.3 urllib.request.urlencode()
**urllib.request.urlencode()
**函数是一个URL编码方法,用于将一个字典(或类似于字典的对象)中的键值对转换为URL编码的字符串。
该函数的语法如下:
python
urllib.request.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)
参数说明:
query
:要转换为URL编码字符串的字典或类似字典的对象。doseq
:如果为True
,则将多个同名的键值对作为单个键值对处理。默认为False
。safe
:指定需要编码的字符集合,其他字符将被编码。默认情况下,会对所有非字母数字字符进行编码。encoding
:指定编码格式,默认为utf-8
。errors
:指定编码错误处理方式,默认为replace
。quote_via
:指定用于引用字符的方法,默认为quote_plus
,即将空格转换为+
符号。
返回值为URL编码字符串。
示例代码:
python
import urllib.request
params = {'name': 'John', 'age': 30}
encoded_params = urllib.request.urlencode(params)
#字典params中的键值对被转换为URL编码字符串name=John&age=30
print(encoded_params) # 输出:name=John&age=30
2.2 urllib.parse
**urllib.parse
**模块是Python标准库中的一个模块,用于解析URL(Uniform Resource Locator)。
URL是用于定位一个具体资源的字符串,它由多个部分组成,包括协议、域名、端口、路径、查询参数和片段等。urllib.parse模块提供了一些函数,用于对URL进行解析、拼接、编码和解码等操作。
urllib.parse 模块的主要函数包括:
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
- 解析URL,返回一个
ParseResult
对象,包含URL的各个组成部分。
- 解析URL,返回一个
urllib.parse.urlunparse(parts)
- 将
ParseResult
对象或包含URL各部分的可迭代对象转换为URL字符串。
- 将
urllib.parse.urljoin(base, url, allow_fragments=True)
- 将一个相对URL和一个基础URL拼接成一个完整的URL。
urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)
- 将字典或元组列表等数据序列化为URL编码的查询字符串。
urllib.parse.parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None)
- 解析URL编码的查询字符串,返回一个字典,键为参数名,值为参数值的列表。
urllib.parse.quote(string, safe='/', encoding=None, errors=None)
- 对字符串进行URL编码。
urllib.parse.unquote(string, encoding='utf-8', errors='replace')
- 对URL编码的字符串进行解码。
这些函数可以帮助我们处理URL相关的操作,如解析URL、构建URL、编码和解码URL等。
2.2.1 urllib.parse.urlparse()
urllib.parse.urlparse()函数是Python中的一个函数,用于解析URL字符串,并返回一个具有以下属性的命名元组:
- scheme:URL的协议(例如http,https等)
- netloc:网络位置部分(例如www.example.com)
- path:URL的路径部分
- params:URL的参数部分
- query:URL的查询字符串部分
- fragment:URL的片段标识符部分
例子:
python
from urllib.parse import urlparse
url = 'https://www.example.com/path/to/page?param1=value1¶m2=value2#fragment'
parsed_url = urlparse(url)
print(parsed_url.scheme) # 输出:https
print(parsed_url.netloc) # 输出:www.example.com
print(parsed_url.path) # 输出:/path/to/page
print(parsed_url.params) # 输出:
print(parsed_url.query) # 输出:param1=value1¶m2=value2
print(parsed_url.fragment) # 输出:fragment
2.2.2 urllib.parse.urlunparse()
urllib.parse.urlunparse()函数是Python中的一个urllib模块下的函数,用于将一个URL的各个组成部分拼接成一个完整的URL。
函数原型:
python
urllib.parse.urlunparse(parts)
参数说明:
- parts: 由6个元素构成的元组或列表,表示一个完整的URL的各个组成部分,分别是:scheme(协议)、netloc(网络位置)、path(路径)、params(参数)、query(查询字符串)、fragment(锚点)。
返回值: 返回一个完整的URL。
示例:
python
from urllib.parse import urlunparse
url_parts = ('https', 'www.example.com', '/path', '', 'key=value', 'fragment')
url = urlunparse(url_parts)
print(url)
# https://www.example.com/path?key=value#fragment 输出结果
2.2.3 urllib.parse.urljoin()
urllib.parse.urljoin()
函数用于拼接URL地址。它将一个基础URL和一个相对URL作为参数,然后返回一个完整的URL。
函数原型:
python
urllib.parse.urljoin(base_url, relative_url)
参数说明:
base_url
:基础URL,拼接的起点。relative_url
:相对URL,要拼接到基础URL后面的部分。
urllib.parse.urljoin()
函数会自动处理各种情况,确保生成的URL是正确的。它会根据相对URL的情况来决定应该如何拼接。
- 如果相对URL以
/
开头,那么它会被拼接到基础URL的根路径下; - 如果相对URL以
//
开头,那么它会被拼接到基础URL的scheme下; - 如果相对URL以
./
或者../
开头,那么它会被拼接到基础URL的路径下。
下面是一个示例:
python
from urllib.parse import urljoin
base_url = 'https://www.example.com/'
relative_url = 'about'
full_url = urljoin(base_url, relative_url)
print(full_url)
# 输出结果 https://www.example.com/about
在这个例子中,urljoin()函数将基础URL https://www.example.com/ 和 相对URL about 拼接起来,生成了一个完整的URL https://www.example.com/about。
2.2.4 urllib.parse.urlencode()
urllib.parse.urlencode()函数是Python标准库中的一个函数,用于将字典或包含元组的可迭代对象转换为URL查询参数字符串。
函数原型:
python
urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)
参数说明:
- query:包含查询参数的字典或可迭代对象。
- doseq:当为True时,如果查询参数的值为列表或元组,则会将它们作为多个值传递;当为False时,只会取列表或元组的第一个值作为查询参数的值。
- safe:指定哪些字符不需要被转义,默认为'/'。
- encoding:指定编码方式,默认为UTF-8。
- errors:指定编码错误的处理方式,默认为'strict'。
- quote_via:指定对查询参数进行编码的方式,默认为quote_plus()。
返回值: 返回URL查询参数字符串。
示例:将一个包含查询参数的字典转换为URL查询参数字符串
python
import urllib.parse
params = {
'name': 'Alice',
'age': 20,
'hobbies': ['hiking', 'reading'],
'city': 'New York'
}
query_string = urllib.parse.urlencode(params)
print(query_string)
# 输出:name=Alice&age=20&hobbies=hiking&hobbies=reading&city=New+York
注意:
- hobbies参数的值为一个列表,而在转换为查询参数字符串时,会将列表的每个元素作为一个单独的值。
2.2.5 urllib.parse.parse_qs()
urllib.parse.parse_qs()函数是Python的urllib库中的一个函数,用于解析URL查询字符串。它会将查询字符串解析为字典,其中查询参数的键是字典的键,查询参数的值是一个列表,列表中包含了查询参数的多个值。
函数原型:
python
urllib.parse.parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace')
参数说明:
- qs:要解析的查询字符串。
- keep_blank_values:指定是否保留空白值,默认为False,表示不保留。
- strict_parsing:指定是否严格解析,默认为False,表示不严格。
- encoding:指定解码查询字符串时使用的编码,默认为'utf-8'。
- errors:指定解码查询字符串时遇到错误时的处理方式,默认为'replace',表示用替代字符替换错误字符。
返回值是一个字典,其中查询参数的键是字典的键,查询参数的值是一个列表,列表中包含了查询参数的多个值。
python
from urllib.parse import parse_qs
qs = 'name=John&age=30&city=New+York&city=London'
result = parse_qs(qs)
print(result)
#输出结果: {'name': ['John'], 'age': ['30'], 'city': ['New York', 'London']}
这里的查询字符串qs,包含了三个查询参数:name、age和city。city是一个重复的查询参数,它出现了两次。parse_qs()函数会将查询字符串解析为一个字典,其中name和age的值分别是一个元素的列表,而city的值是一个包含两个元素的列表。
2.2.6 urllib.parse.quote()
urllib.parse.quote()函数是Python标准库中urllib.parse模块中的一个函数,用于将字符串进行URL编码。它会将字符串中的特殊字符转换为URL安全的形式,以便在URL中使用。
函数的语法如下:
python
urllib.parse.quote(string, safe='/', encoding=None, errors=None)
参数说明:
- string:要进行URL编码的字符串。
- safe:指定保留不编码的字符,默认为'/'。
- encoding:指定字符串的编码方式,默认为None,表示使用UTF-8编码。
- errors:指定编码错误处理方式,默认为None,表示忽略错误。
示例:
python
import urllib.parse
string = 'Hello World!'
encoded_string = urllib.parse.quote(string)
print(encoded_string)
#输出结果 Hello%20World%21
在上面的例子中,原始字符串"Hello World!"被编码为"Hello%20World%21",其中空格被转换为"%20",感叹号被转换为"%21"。
2.2.7 urllib.parse.unquote()
**urllib.parse.unquote()
**是Python中urllib.parse
模块提供的一个函数。它会接受一个URL编码的字符串作为输入,并返回解码后的字符串。它会将任何百分号编码的序列替换为其对应的字符。
参数说明:
-
string
(必需):表示需要解码的URL编码的字符串。该参数是一个字符串类型。 -
encoding
(可选):表示解码时要使用的编码方式。默认值为utf-8
。该参数是一个字符串类型。
示例:
python
from urllib.parse import unquote
encoded_string = "Hello%20World%21"
decoded_string = unquote(encoded_string, encoding='utf-8')
print(decoded_string)
# 输出结果 Hello World!
在这个示例中,使用urllib.parse.unquote()
函数对URL编码的字符串"Hello%20World%21"进行解码。解码时使用utf-8
编码方式。最终得到解码后的字符串"Hello World!"。
2.3 urllib.error
**urllib.error
**模块是Python标准库中的一个模块,提供了处理URL打开和读取错误的异常类。
该模块定义了以下异常类:
-
URLError
:当URL产生错误时引发的异常。它是OSError
的子类,包含了有关URL错误的更多详细信息。 -
HTTPError
:当HTTP URL产生错误时引发的异常。它是URLError
的子类,更专注于HTTP相关的错误。
使用urllib.error
模块,你可以捕获和处理URL操作中可能出现的错误,例如网络连接问题、服务器错误等。
以下是一个使用urllib.error
模块的示例:
python
from urllib.request import urlopen
from urllib.error import URLError, HTTPError
try:
response = urlopen('http://www.example.com/invalid-url')
except HTTPError as e:
print('HTTP Error:', e.code, e.reason)
except URLError as e:
print('URL Error:', e.reason)
else:
print('Success!')
在这个示例中,urlopen()
函数尝试打开一个无效的URL。
- 如果遇到HTTP错误,则捕获
HTTPError
异常并打印错误代码和原因。 - 如果遇到URL错误,则捕获
URLError
异常并打印错误原因。 - 如果没有发生错误,则打印"Success!"。
2.4 urllib.robotparser
**urllib.robotparser
**模块是Python标准库中的一个模块,用于解析和分析robots.txt文件,该文件用于指示爬虫程序应该访问哪些页面。
使用urllib.robotparser
模块,你可以检查指定URL的robots.txt
文件,了解爬虫是否被允许访问该URL。
该模块提供了**RobotFileParser
**类,它具有以下主要方法:
-
set_url(url)
:设置要解析的robots.txt
文件的URL。 -
read()
:从指定URL中读取robots.txt
文件,并进行解析。 -
parse(lines)
:解析给定的robots.txt
文件内容。lines
参数是一个包含文件内容的字符串列表。 -
can_fetch(useragent, url)
:判断指定的爬虫(useragent
)是否被允许访问指定的URL。
下面是一个使用urllib.robotparser
模块的示例:
python
from urllib.robotparser import RobotFileParser
# 创建RobotFileParser对象
rp = RobotFileParser()
# 设置要解析的robots.txt文件的URL
rp.set_url('http://www.example.com/robots.txt')
# 读取并解析robots.txt文件
rp.read()
# 判断爬虫是否允许访问指定URL
allowed = rp.can_fetch('mybot', 'http://www.example.com/some-page.html')
if allowed:
print('Access allowed')
else:
print('Access denied')
在这个示例中,RobotFileParser
对象被创建,并设置要解析robots.txt
文件的URL。然后通过read()
方法读取并解析robots.txt
文件。最后,使用can_fetch()
方法判断指定的爬虫是否被允许访问指定的URL,并打印相应的访问结果。
注意:
can_fetch()
方法的第一个参数是表示爬虫的字符串,它必须与robots.txt
文件中的User-agent
字段匹配。
2.4.1 set_url()
**set_url(url)
**是RobotFileParser
类的一个方法,用于设置要解析的robots.txt
文件的URL。
参数说明:
url
:要解析的robots.txt
文件的URL,必须是一个合法的URL字符串。
该方法可以在创建RobotFileParser
对象后使用,并且在调用read()方法之前使用。
示例用法:
python
from urllib.robotparser import RobotFileParser
# 创建RobotFileParser对象
rp = RobotFileParser()
# 设置要解析的robots.txt文件的URL
rp.set_url('http://www.example.com/robots.txt')
在这个示例中,首先创建了一个RobotFileParser
对象,然后使用set_url()
方法设置要解析的robots.txt
文件的URL为'http://www.example.com/robots.txt'。接下来可以调用read()
方法来读取和解析该文件。
2.4.2 read()
**read()
**是RobotFileParser
类的一个方法,用于读取并解析指定的robots.txt文件。该方法会根据之前通过set_url()
方法设置的URL,从网页中获取robots.txt
文件内容,并进行解析。
注意:
- 在调用
read()
方法之前,必须先通过set_url()
方法设置要解析的robots.txt
文件的URL。
示例用法:
python
from urllib.robotparser import RobotFileParser
# 创建RobotFileParser对象
rp = RobotFileParser()
# 设置要解析的robots.txt文件的URL
rp.set_url('http://www.example.com/robots.txt')
# 读取并解析robots.txt文件
rp.read()
在这个示例中,首先创建了一个RobotFileParser
对象,然后使用set_url()
方法设置要解析的robots.txt
文件的URL为'http://www.example.com/robots.txt',最后调用read()
方法来读取并解析该文件。
2.4.3 can_fetch()
urllib.robotparser.can_fetch() 方法是一个用来检查给定的User-Agent是否可以fetch(抓取)给定的URL的方法。它接收两个参数:User-Agent和URL。如果可以抓取该URL,它返回True;否则返回False。
方法原型:
python
can_fetch(useragent, url)
参数说明:
- useragent是一个字符串,表示User-Agent;
- url是一个字符串,表示URL。
示例:
python
from urllib.robotparser import RobotFileParser
# 创建一个RobotFileParser对象
rp = RobotFileParser()
# 设置robots.txt文件的URL
rp.set_url("http://www.example.com/robots.txt")
# 读取并解析robots.txt文件
rp.read()
# 检查User-Agent为"Mozilla/5.0"是否可以抓取"http://www.example.com/page.html"
can_fetch = rp.can_fetch("Mozilla/5.0", "http://www.example.com/page.html")
print(can_fetch)
# 输出结果 True
上述示例中,首先创建了一个RobotFileParser对象,并通过调用set_url()方法设置了要解析的robots.txt文件的URL。然后,调用read()方法读取并解析了robots.txt文件。最后,通过调用can_fetch()方法,检查User-Agent为"Mozilla/5.0"是否可以抓取"url",并将结果打印出来。在这个示例中,由于robots.txt文件中允许"Mozilla/5.0"抓取"http://www.example.com/page.html",所以输出结果为True。
三、unllib.post请求
POST请求是一种HTTP请求方法,用于向服务器提交数据。以下是一个示例的Python代码,演示如何发送一个POST请求:
python
import urllib.request
import urllib.parse
# 请求的URL
url = 'http://example.com/post'
# 要提交的数据
data = {'name': 'John', 'age': 30}
# 将数据编码为URL格式
data_encoded = urllib.parse.urlencode(data).encode('utf-8')
# 创建Request对象
req = urllib.request.Request(url, data_encoded)
# 发送POST请求并获取响应
response = urllib.request.urlopen(req)
# 读取响应内容
result = response.read()
# 打印响应内容
print(result)
在示例中,使用urllib库的request模块发送了一个POST请求。首先,我们指定了要请求的URL。然后,我们准备了要提交的数据,并使用urllib库的parse模块将数据编码为URL格式。接下来,我们创建了一个Request对象,将URL和编码后的数据作为参数传入。最后,我们使用urllib库的urlopen函数发送POST请求并获取响应。最后,我们将响应内容打印出来。