Python
基础语法
01概念
02安装
03变量
04字符串
05数
06常量与注释
07列表
08元组
09if语句
10字典
11集合
12复合数据类型对比
13推导式
14用户输入
15while循环
16函数
17类
18面向对象编程
19文件操作
20异常处理
21日期和时间
22魔术方法
23内置函数
24线程
25并发&并行
26正则表达式
27迭代器
28装饰器
29生成器
30上下文管理器
31函数式编程
32闭包
33解包
34工具库
35连接关系型数据库
36虚拟环境
37异步编程
网络爬虫
01urllib库[了解]
02requests库
03数据交换格式
04解析库
05lxml
06Beautiful Soup
07Xpath语法
08动态网页的处理
-
+
首页
01urllib库[了解]
urllib 是 Python 标准库中用于**处理 URL 相关操作**的核心模块集,无需额外安装即可使用,是实现简单网络爬虫、发送 HTTP 请求、解析 URL 等功能的基础工具。 它整合了多个子模块,覆盖从请求发送到异常处理、URL 解析的全流程,是新手学习网络爬虫时必须掌握的基础库之一。 ## 概述 urllib 并非单一模块,而是由 **4 个功能明确的子模块** 组成,各模块分工协作,共同完成 URL 相关任务: | 子模块 | 核心功能 | | ------------------ | ------------------------------------------------------------ | | urllib.request | 发送 HTTP/HTTPS 请求、获取服务器响应(最核心模块,爬虫核心功能依赖它) | | urllib.parse | 解析 URL 结构(拆分 / 拼接 URL)、处理 URL 编码(如中文、特殊字符转义) | | urllib.error | 捕获和处理请求过程中的异常(如网络错误、HTTP 状态码错误) | | urllib.robotparser | 解析网站的 robots.txt 文件,判断爬虫是否有权限访问目标 URL(合规爬取) | ## 核心优势 **原生标准库**:Python 自带,无需 pip install,环境兼容性强(尤其在受限环境中); **功能全面**:覆盖请求发送、URL 处理、异常捕获、合规校验,满足简单爬虫需求; **稳定性高**:与 Python 版本同步更新,API 兼容性强,适合基础场景。 ## 适用场景 简单网络爬虫(获取静态网页内容、提交表单); URL 解析与编码(处理请求参数、拼接合法 URL); 基础 HTTP 交互(无需复杂会话管理、Cookie 处理的场景)。 ## 核心子模块 ### urllib.request urllib.request 是 urllib 的核心,负责**向目标 URL 发送 HTTP 请求(GET/POST 等),并接收服务器返回的响应数据**。 其核心能力包括:发送请求、设置请求头、处理代理、管理 Cookie 等。 基础函数:urlopen(url, data=None, timeout=..., context=...) 是最基础的请求函数,用于发送 HTTP/HTTPS 请求并返回 HTTPResponse 响应对象。 | 参数 | 作用 | | ------- | ------------------------------------------------------------ | | url | 目标 URL(字符串或 Request 对象,必传) | | data | POST 请求的表单数据(需为 bytes 类型,默认 None 表示 GET 请求) | | timeout | 请求超时时间(秒,防止请求无限阻塞,建议设置) | | context | SSL 上下文(处理 HTTPS 证书验证,如忽略证书错误) | urlopen() 返回的 HTTPResponse 对象包含服务器响应的所有信息,常用方法如下: | 法 / 属性 | 作用 | | --------------- | ------------------------------------------------------------ | | read(size=-1) | 读取响应体(bytes 类型),size=-1 表示读取全部内容 | | readline() | 按行读取响应体(适合大文件,避免内存溢出) | | getcode() | 获取 HTTP 状态码(如 200 表示成功,404 表示未找到,500 表示服务器错误) | | getheaders() | 获取响应头(列表形式,每个元素为 (键, 值) 元组) | | getheader(name) | 获取指定响应头(如 getheader("Content-Type") 获取内容类型) | | url | 获取最终请求的 URL(可能因重定向变化) | 例如:发送GET请求。 ```python import urllib.request url = "http://maolin101.com/" try: response = urllib.request.urlopen(url, timeout=5) html_content = response.read().decode('utf-8') print("Code: ", response.getcode()) print("Content-Type: ", response.getheader("Content-Type")) print("url: ", response.url) except Exception as e: print(e) ``` 输出结果: ```python Code: 200 Content-Type: text/html; charset=UTF-8 url: https://maolin101.com/ ``` ### 自定义请求头 urlopen() 功能较简单,无法直接设置请求头(如 User-Agent、Referer)。 Request 类可自定义请求头,用于**模拟浏览器行为、绕过基础反爬**(很多网站会拦截无 User-Agent 的请求)。 ```python import urllib.request # 目标 URL url = "https://maolin101.com" # 1. 自定义请求头(关键:添加 User-Agent,模拟 Chrome 浏览器) headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", "Referer": "https://www.baidu.com/" # 可选,模拟从百度首页跳转 } try: # 2. 创建 Request 对象(整合 URL 和请求头) req = urllib.request.Request(url=url, headers=headers) # 3. 发送请求(urlopen 接收 Request 对象) response = urllib.request.urlopen(req, timeout=5) # 4. 验证结果 print("状态码:", response.getcode()) print("响应头 User-Agent 验证:", response.getheader("Server")) # 查看服务器信息 except Exception as e: print("请求失败:", str(e)) ``` 输出结果: ```python 状态码: 200 响应头 User-Agent 验证: nginx ``` ### urllib.parse URL 中常包含特殊字符(如中文、空格、& 等),需通过编码转为合法格式;同时,爬虫中可能需要拆分 URL 结构(如提取域名、请求参数),urllib.parse 正是用于处理这些需求。 | 函数 | 功能描述 | | ----------------- | ------------------------------------------------------------ | | urlparse() | 拆分 URL 为 6 个部分:scheme(协议)、netloc(域名)、path(路径)、params(参数)、query(查询字符串)、fragment(锚点) | | urlunparse() | 反向操作:将 urlparse() 拆分的 6 部分拼接为完整 URL | | urlencode() | 将字典转为 URL 查询字符串(如 {"name":"张三","age":20} → name=%E5%BC%A0%E4%B8%89&age=20) | | parse_qs() | 将 URL 查询字符串转为字典(反向 urlencode()) | | quote(s, safe='') | 对字符串进行 URL 编码(如中文 → %E5%BC%A0%E4%B8%89) | | unquote(s) | 对 URL 编码字符串解码(反向 quote()) | 拆分URL ```python import urllib.parse # 目标 URL(包含协议、域名、路径、查询参数、锚点) url = "https://search.baidu.com/s?wd=python%20urllib&rsv_spt=1#result" # 拆分 URL parsed_url = urllib.parse.urlparse(url) print("拆分结果:") print("协议(scheme):", parsed_url.scheme) # https print("域名(netloc):", parsed_url.netloc) # search.baidu.com print("路径(path):", parsed_url.path) # /s print("查询参数(query):", parsed_url.query) # wd=python%20urllib&rsv_spt=1 print("锚点(fragment):", parsed_url.fragment)# result ``` 输出结果: ```python 拆分结果: 协议(scheme): https 域名(netloc): search.baidu.com 路径(path): /s 查询参数(query): wd=python%20urllib&rsv_spt=1 锚点(fragment): result ``` ### urllib.error 网络请求中可能出现多种错误(如网络断开、URL 不存在、服务器拒绝访问),urllib.error 定义了两类核心异常,用于捕获和处理这些错误: | 常类 | 异常类型 | 常见场景示例 | | --------- | ------------------------------------------------------------ | --------------------------------------------------------- | | URLError | **通用错误**(父类),涵盖所有与 URL 相关的错误(非 HTTP 状态码错误) | 网络断开、域名不存在(如 www.baidu123.com)、超时 | | HTTPError | **HTTP 状态码错误**(子类),仅当服务器返回错误状态码时触发(如 4xx、5xx) | 404(页面不存在)、403(拒绝访问)、500(服务器内部错误) | 注意:HTTPError 是 URLError 的子类,捕获时需**先捕子类,再捕父类**(否则子类异常会被父类捕获,无法区分具体错误类型)。 ```python import urllib.request import urllib.error # 测试 3 种错误场景:1. 404 错误;2. 域名不存在;3. 超时 test_urls = [ "https://www.baidu.com/404_page", # 1. 404 页面不存在 "https://www.baidu123.com", # 2. 域名不存在 "https://www.baidu.com", # 3. 正常 URL(用于对比) ] for url in test_urls: try: response = urllib.request.urlopen(url, timeout=5) print(f"\n{url} 请求成功,状态码:", response.getcode()) except urllib.error.HTTPError as e: # 捕获 HTTP 状态码错误 print(f"{url} HTTP 错误:") print("\t状态码:", e.code) # 错误状态码(如 404) print("\t错误原因:", e.reason) # 错误原因(如 Not Found) print("\t响应头:", e.headers) # 错误响应的头部信息 except urllib.error.URLError as e: # 捕获通用 URL 错误(如域名不存在、超时) print(f"\n{url} URL 错误:", str(e)) except Exception as e: # 捕获其他未知错误 print(f"{url} 未知错误:", e) ``` 输出结果: ```python https://www.baidu.com/404_page HTTP 错误: 状态码: 404 错误原因: Not Found 响应头: Content-Length: 206 Content-Type: text/html; charset=iso-8859-1 Date: Wed, 03 Sep 2025 07:31:59 GMT Server: Apache Connection: close https://www.baidu123.com URL 错误: <urlopen error timed out> https://www.baidu.com 请求成功,状态码: 200 ``` ### urllib.robotparser 网站通过 robots.txt 文件(位于网站根目录,如 https://www.baidu.com/robots.txt)定义 “爬虫规则”,告知爬虫哪些页面可爬、哪些不可爬。urllib.robotparser 用于解析该文件,帮助爬虫遵守规则,避免违规。 RobotFileParser 是核心类,常用方法如下: | 方法 | 功能描述 | | -------------------------- | ------------------------------------------------------------ | | set_url(robots_url) | 设置 robots.txt 的 URL(如 https://www.baidu.com/robots.txt) | | read() | 读取并解析 robots.txt 内容(需在 set_url() 后调用) | | can_fetch(user_agent, url) | 判断指定 User-Agent 的爬虫是否有权限爬取目标 url(返回 True/False) | | parse(lines) | 直接解析 robots.txt 的文本内容(需传入每行文本的列表) | ```python import urllib.robotparser # 1. 创建 RobotFileParser 对象 rp = urllib.robotparser.RobotFileParser() # 2. 设置目标网站的 robots.txt URL robots_url = "https://www.baidu.com/robots.txt" rp.set_url(robots_url) # 3. 读取并解析 robots.txt rp.read() # 4. 定义爬虫的 User-Agent(需与请求头中的 User-Agent 一致) user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/124.0.0.0 Safari/537.36" # 5. 判断是否可爬取目标 URL test_urls = [ "https://www.baidu.com/s?wd=python", # 百度搜索页面 "https://www.baidu.com/baidu.html", # 假设的禁止爬取页面 ] for url in test_urls: if rp.can_fetch(user_agent, url): print(f" {user_agent} 有权限爬取 {url}") else: print(f" {user_agent} 无权限爬取 {url}") ``` 输出结果: ```python Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/142.0 无权限爬取 https://www.baidu.com/s?wd=python Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/142.0 无权限爬取 https://www.baidu.com/baidu.html ```
毛林
2025年9月7日 12:11
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码