1 什么是urllib
urllib是Python标准库中的一个模块,用于处理URL(Uniform Resource Locator)相关的操作。它提供了一系列函数和类,方便开发人员在Python程序中进行URL请求、数据获取、参数编码等操作。
urllib库包含四个子模块:urllib.request、urllib.parse、urllib.error和urllib.robotparser。
通过urllib库,开发人员可以实现从网络上获取数据、发送HTTP请求、处理URL等功能。它是进行Web开发和网络爬虫编程时常用的工具之一,为Python程序提供了方便和灵活性。
2 urllib.request模块
urllib.request模块是urllib库中的一个子模块,用于发送HTTP请求、获取远程数据和处理URL操作。它提供了一系列函数和类来执行这些操作。
基本用法如下:
- 导入
由于这个库是python自带的,所以不需要pip install
import urllib.request
- 发送GET请求
在上一篇文章中( 【Python爬虫开发基础⑥】计算机网络基础(Web和HTTP)),我们已经介绍了HTTP报文格式,并且介绍了请求头中开始行的常用方法,下面的GET和POST请求就是其中的方法。
使用urlopen()
函数发送HTTP GET请求,并接收服务器返回的数据。
# 首先定义一个要发送请求的URL url = 'https://csdn.net' # 使用urlopen发送get请求 response = urllib.request.urlopen(url)
- 获取服务器响应
上面一步通过response接收了服务器的响应,可以使用.read()
方法读取服务器响应的内容,并将其存储在变量中。
content = response.read()
- 处理响应内容
可以对获取到的响应内容进行进一步的处理,例如解码字节流、解析HTML等操作。
# 将获取到的响应解码为utf-8格式 content = content.urldecode('utf-8')
- 发送POST请求
如果需要发送POST请求,可以使用urllib.parse.urlencode()
函数编码POST请求的参数,并使用.data
属性传递给请求对象
import urllib.parse data = urllib.parse.urlencode({"key": "value"}).encode() request = urllib.request.Request(url, data=data, method="POST") # 创建POST请求对象 response = urllib.request.urlopen(request) # 发送POST请求并获取响应
- 设置请求头
这一个操作尤为关键,在一般情况下,为了伪装成一个浏览器,需要设置请求时发送的UA。可以通过创建Request对象,并设置请求头信息来发送定制化的请求,例如User-Agent、Referer等。
headers = {"User-Agent": "Mozilla/5.0"} request = urllib.request.Request(url, headers=headers) response = urllib.request.urlopen(request)
3 urllib.parse模块
urllib.parse 模块是 Python 标准库中的一部分,用于解析和操作 URL。它提供了一组函数,可以将 URL 拆分为各个组成部分,或者将各个组成部分合并为完整的 URL。
- 解析 URL
urlparse(url, scheme='', allow_fragments=True)
:解析 URL 字符串并返回一个具名元组,包含 URL 的各个组成部分。
from urllib.parse import urlparse url = 'https://www.example.com/path?query=hello#fragment' parsed_url = urlparse(url) print(parsed_url.scheme) # 输出:https print(parsed_url.netloc) # 输出:www.example.com print(parsed_url.path) # 输出:/path print(parsed_url.query) # 输出:query=hello print(parsed_url.fragment) # 输出:fragment
- 构建 URL
urlunparse(parts)
:将 URL 的各个部分组合成完整的 URL 字符串。
from urllib.parse import urlunparse parts = ('https', 'www.example.com', '/path', '', 'query=hello', 'fragment') url = urlunparse(parts) print(url) # 输出:https://www.example.com/path?query=hello#fragment
- 编码和解码 URL 参数
urlencode(query, doseq=False, safe='', encoding=None, errors=None)
:将字典或元组列表形式的查询参数编码为 URL 字符串。
parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None)
:将 URL 查询字符串解析为字典形式的查询参数。
from urllib.parse import urlencode, parse_qs params = {'key': 'value', 'foo': ['bar', 'baz']} encoded_params = urlencode(params) print(encoded_params) # 输出:key=value&foo=bar&foo=baz decoded_params = parse_qs(encoded_params) print(decoded_params) # 输出:{'key': ['value'], 'foo': ['bar', 'baz']}
- 编码和解码 URL 特殊字符
quote(string, safe='/', encoding=None, errors=None)
:将字符串中的特殊字符进行 URL 编码。
unquote(string, encoding='utf-8', errors='replace')
:将 URL 编码的字符串进行解码,恢复特殊字符的原始形式。
from urllib.parse import quote, unquote string = 'Hello World!@#$' quoted_string = quote(string) print(quoted_string) # 输出:Hello%20World%21%40%23%24 unquoted_string = unquote(quoted_string) print(unquoted_string) # 输出:Hello World!@#$
4 urllib.error模块
urllib.error 模块是 Python 标准库中的一部分,用于处理与 urllib 请求和打开 URL 相关的错误。它提供了一些异常类,用于捕获和处理在使用 urllib 过程中可能出现的异常情况。
- 异常类
URLError
:用于处理 URL 相关的错误,如无法连接到服务器、网络问题等。
HTTPError
:继承自 URLError,用于处理 HTTP 相关的错误,如页面不存在(404)、权限问题等。
- 捕获异常
使用 try-except
结构可以捕获并处理 urllib.error
模块抛出的异常。
from urllib import request, error url = 'https://www.example.com/404' try: response = request.urlopen(url) except error.HTTPError as e: print(f'HTTP Error: {e.code} - {e.reason}') except error.URLError as e: print(f'URL Error: {e.reason}')
我们尝试打开一个不存在的 URL 'https://www.example.com/404'
,如果出现 HTTPError
异常,则打印 HTTP 响应状态码和原因;如果出现 URLError
异常,则打印 URL 错误原因。
- 获取错误信息
URLError
和 HTTPError
异常对象提供了一些属性来获取更详细的错误信息。
from urllib import request, error url = 'https://www.example.com/404' try: response = request.urlopen(url) except error.HTTPError as e: print(f'HTTP Error: {e.code} - {e.reason}') print(e.headers) except error.URLError as e: print(f'URL Error: {e.reason}')
如果捕获到 HTTPError
异常,我们可以通过 e.code
和 e.reason
分别获取响应的状态码和原因字符串,通过 e.headers
获取响应的头部信息。
5 urllib.robotparser 模块
urllib.robotparser 模块是 Python 标准库中的一部分,用于解析和分析 robots.txt 文件。robots.txt 是一个遵循 Robots Exclusion Protocol(机器人排除协议)的文本文件,用于指示网络爬虫哪些页面可以访问,哪些页面需要排除访问。urllib.robotparser 模块提供了一个 RobotFileParser 类,用于解析 robots.txt 文件并提供方法来判断一个 URL 是否允许被爬取。
- 创建 RobotFileParser 对象
使用 RobotFileParser
类的构造函数可以创建一个对象,并使用 set_url()
方法传入 robots.txt 文件的 URL。
from urllib.robotparser import RobotFileParser url = 'http://www.example.com/robots.txt' parser = RobotFileParser() parser.set_url(url)
- 读取和分析 robots.txt 文件
使用 read()
方法从 robots.txt 文件中读取内容,并使用 parse()
方法解析读取的内容。
from urllib.robotparser import RobotFileParser url = 'http://www.example.com/robots.txt' parser = RobotFileParser() parser.set_url(url) parser.read() parser.parse()
- 判断 URL 是否允许访问
使用 can_fetch()
方法判断给定的 User-Agent 是否允许访问特定的 URL。
from urllib.robotparser import RobotFileParser url = 'http://www.example.com/robots.txt' user_agent = 'MyCrawler' path = '/path/to/page' parser = RobotFileParser() parser.set_url(url) parser.read() parser.parse() if parser.can_fetch(user_agent, path): print(f'{user_agent} is allowed to access {path}') else: print(f'{user_agent} is not allowed to access {path}')
首先创建一个 RobotFileParser
对象,并设置 robots.txt 文件的 URL,然后读取和解析该文件。最后,使用 can_fetch()
方法判断给定的 User-Agent 是否允许访问特定的 URL,并进行相应的输出。
通过urllib库,我们可以实现从网络上获取数据、发送HTTP请求、处理URL等功能。它是进行Web开发和网络爬虫编程时常用的工具之一,为Python程序提供了方便和灵活性。