From 2a7f86237774eb7a1b524be9553d753e53b9abfb Mon Sep 17 00:00:00 2001 From: "zhouzhongping@7wate.com" Date: Tue, 29 Aug 2023 14:37:11 +0800 Subject: [PATCH] =?UTF-8?q?Python=EF=BC=9Aurllib=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{第三方模块 => 拓展模块}/_category_.json | 4 +- .../互联网协议和支持/urllib URL 处理模块.md | 329 ++++++++++++++++++ .../{os --- 多种操作系统接口.md => os 多种操作系统接口.md} | 25 +- 3 files changed, 352 insertions(+), 6 deletions(-) rename wiki/programming-language/Python/进阶/{第三方模块 => 拓展模块}/_category_.json (52%) create mode 100644 wiki/programming-language/Python/进阶/标准库/互联网协议和支持/urllib URL 处理模块.md rename wiki/programming-language/Python/进阶/标准库/通用操作系统服务/{os --- 多种操作系统接口.md => os 多种操作系统接口.md} (86%) diff --git a/wiki/programming-language/Python/进阶/第三方模块/_category_.json b/wiki/programming-language/Python/进阶/拓展模块/_category_.json similarity index 52% rename from wiki/programming-language/Python/进阶/第三方模块/_category_.json rename to wiki/programming-language/Python/进阶/拓展模块/_category_.json index 1b427b63..8183daa7 100644 --- a/wiki/programming-language/Python/进阶/第三方模块/_category_.json +++ b/wiki/programming-language/Python/进阶/拓展模块/_category_.json @@ -1,8 +1,8 @@ { - "label": "第三方模块", + "label": "拓展模块", "position": 3, "link": { "type": "generated-index", - "title": "第三方模块" + "title": "拓展模块" } } \ No newline at end of file diff --git a/wiki/programming-language/Python/进阶/标准库/互联网协议和支持/urllib URL 处理模块.md b/wiki/programming-language/Python/进阶/标准库/互联网协议和支持/urllib URL 处理模块.md new file mode 100644 index 00000000..f44651ea --- /dev/null +++ b/wiki/programming-language/Python/进阶/标准库/互联网协议和支持/urllib URL 处理模块.md @@ -0,0 +1,329 @@ +--- +title: urllib URL 处理模块 +description: urllib URL 处理模块 +keywords: +- python +- urllib +tags: +- python +- 标准库 +sidebar_position: 1 +author: 7Wate +date: 2023-08-29 +--- + +## 概述 + +`urllib`是 Python 标准库中用于处理 URL(统一资源定位符)相关操作的模块,它提供了多个子模块,用于执行网络请求、解析 URL、处理错误以及解析 robots.txt 文件等。以下是`urllib`的子模块: + +### 子模块 + +- **`urllib.request`**:提供打开和读取URL的功能。支持多种网络协议,如 HTTP、FTP 等。 +- **`urllib.error`**:包含与网络请求相关的异常类,用于处理错误和异常情况。 +- **`urllib.parse`**:用于解析和构建 URL,提供各种操作,如分割、组合、编码和解码。 +- **`urllib.robotparser`**:用于解析网站的`robots.txt`文件,确定哪些页面可以被爬取。 + +### 优点 + +- **内置模块**:作为 Python 标准库的一部分,无需单独安装。 +- **全面功能**:支持多种网络协议和操作,适用于多种网络操作需求。 +- **高度可定制**:用于处理 URL 的多个方面,如打开、读取、解析等。 + +### 缺点 + +- **较低层次的API**:与一些第三方库相比(如`requests`),`urllib`的API较为底层,可能需要编写更多的代码。 +- **繁琐的错误处理**:错误处理需要额外的代码,相比使用像`requests`这样的库可能更复杂。 + +### 同类产品对比 + +| 产品 | 优点 | 缺点 | 适用背景 | 社区支持 | +| -------- | ------------ | ------------ | ------------------ | ----------- | +| urllib | 标准库,全面 | API 较底层 | 网络请求,URL 操作 | Python 社区 | +| requests | API 简单 | 需要单独安装 | HTTP 请求 | Python 社区 | +| httplib2 | 功能丰富 | 使用复杂 | HTTP 请求 | Python 社区 | + +## `urllib.request` + +| 方法 | 功能描述 | 示例 | +| ------------------------ | ------------------------------------ | ------------------------------------------------------------ | +| `urlopen()` | 打开并读取一个 URL 的内容 | `urllib.request.urlopen(url)` | +| `urlretrieve()` | 将 URL 指向的文件下载到本地 | `urllib.request.urlretrieve(url, filename)` | +| `build_opener()` | 构建一个可自定义的 `Opener` 对象 | `opener = urllib.request.build_opener()` | +| `install_opener()` | 安装全局的 `Opener` | `urllib.request.install_opener(opener)` | +| `HTTPBasicAuthHandler()` | HTTP 基础认证处理程序 | `handler = urllib.request.HTTPBasicAuthHandler()` | +| `HTTPCookieProcessor()` | 用于处理 HTTP cookies | `handler = urllib.request.HTTPCookieProcessor()` | +| `ProxyHandler()` | 设置代理 | `proxy = urllib.request.ProxyHandler({'http': 'http://www.example.com:8080'})` | +| `Request()` | 创建一个请求对象,用于定制 HTTP 头等 | `req = urllib.request.Request(url, headers={...})` | + +### `urlopen()` 打开 URL + +```python +import urllib.request + +# 打开一个网页 +response = urllib.request.urlopen('http://www.example.com') + +# 读取网页内容 +data = response.read() + +# 输出网页内容 +print(data) +``` + +### `urlretrieve()` 下载文件 + +```python +import urllib.request + +# 从指定 URL 下载文件,并保存到本地 +urllib.request.urlretrieve('http://www.example.com/file.txt', 'local_file.txt') +``` + +### `build_opener()` 和 `install_opener()` + +`build_opener()` 传递一系列处理程序(handlers),这些处理程序用于定义如何处理各种 HTTP 功能,比如重定向、基础认证、cookies 等。一旦你使用 `build_opener()` 创建了一个 `Opener` 对象,你可以使用 `install_opener()` 来设置它作为默认的 `Opener`。 + +```python +import urllib.request + +# 创建基础认证处理程序 +auth_handler = urllib.request.HTTPBasicAuthHandler() +auth_handler.add_password('realm', 'host', 'username', 'password') + +# 创建代理处理程序 +proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.proxy.com:8080'}) + +# 创建 Opener +opener = urllib.request.build_opener(auth_handler, proxy_handler) + +# 安装 Opener +urllib.request.install_opener(opener) + +# 使用 urlopen() 方法,这样会应用我们之前设置的所有处理程序 +response = urllib.request.urlopen('http://www.example.com') +``` + +### HTTP 基础认证 (`HTTPBasicAuthHandler`) + +```python +import urllib.request + +# 创建一个 HTTPBasicAuthHandler 对象 +auth_handler = urllib.request.HTTPBasicAuthHandler() + +# 添加认证信息 +auth_handler.add_password('realm', 'host', 'username', 'password') + +# 创建并安装 opener +opener = urllib.request.build_opener(auth_handler) +urllib.request.install_opener(opener) +``` + +### `HTTPCookieProcessor` 处理 cookies + +```python +import urllib.request +import http.cookiejar + +# 创建一个 CookieJar 对象 +cookie_jar = http.cookiejar.CookieJar() + +# 创建一个 HTTPCookieProcessor 对象 +cookie_handler = urllib.request.HTTPCookieProcessor(cookie_jar) + +# 构建和安装 opener +opener = urllib.request.build_opener(cookie_handler) +``` + +### `ProxyHandler` 设置代理 + +```python +import urllib.request + +# 创建一个 ProxyHandler 对象 +proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.proxy.com:8080'}) + +# 构建并安装 opener +opener = urllib.request.build_opener(proxy_handler) +``` + +### `Request()` 自定义请求 + +```python +import urllib.request + +# 创建一个 Request 对象 +req = urllib.request.Request(url='http://www.example.com', headers={'User-Agent': 'MyApp/1.0'}) + +# 使用 urlopen 打开自定义的请求 +response = urllib.request.urlopen(req) +``` + +## `urllib.error` + +| 方法 | 功能描述 | +| ---------------------- | ------------------------------------- | +| `URLError` | 所有 `urllib` 产生的异常的基类 | +| `HTTPError` | 处理 HTTP 错误状态,继承自 `URLError` | +| `ContentTooShortError` | 在下载过程中,数据不足时抛出的异常 | + +### `URLError` + +当使用 `urllib.request` 打开一个 URL 失败时,通常会抛出 `URLError` 异常。 + +```python +import urllib.request +import urllib.error + +try: + response = urllib.request.urlopen('http://www.nonexistentwebsite.com') +except urllib.error.URLError as e: + print(e.reason) +``` + +### `HTTPError` + +当服务器返回 HTTP 错误状态码(如 404、500 等)时,会抛出 `HTTPError`。 + +```python +import urllib.request +import urllib.error + +try: + response = urllib.request.urlopen('http://www.example.com/404') +except urllib.error.HTTPError as e: + print(f'HTTP Error Code: {e.code}') + print(f'Reason: {e.reason}') +``` + +### `ContentTooShortError` + +如果使用 `urlretrieve()` 函数,但获取的数据长度与 `Content-Length` 头中声明的长度不匹配时,会抛出 `ContentTooShortError`。 + +```python +import urllib.request +import urllib.error + +try: + urllib.request.urlretrieve('http://www.example.com/file', 'local_file.txt') +except urllib.error.ContentTooShortError as e: + print('The downloaded data is less than expected.') +``` + +## `urllib.parse` + +| 方法 | 功能描述 | 示例 | +| -------------- | ------------------------------------ | --------------------------------------- | +| `urlparse()` | 解析 URL,返回一个 ParseResult 对象 | `urllib.parse.urlparse(url)` | +| `urlunparse()` | 将 ParseResult 对象转回 URL | `urllib.parse.urlunparse(parse_result)` | +| `urlsplit()` | 类似于 `urlparse()`,但不分割 params | `urllib.parse.urlsplit(url)` | +| `urlunsplit()` | 将由 `urlsplit()` 返回的对象转回 URL | `urllib.parse.urlunsplit(split_result)` | +| `urljoin()` | 合并两个 URL | `urllib.parse.urljoin(base, url)` | +| `urlencode()` | 将字典或序列转换为 URL 查询字符串 | `urllib.parse.urlencode(query_dict)` | +| `quote()` | 将字符串进行 URL 编码 | `urllib.parse.quote(string)` | +| `unquote()` | 对 URL 编码的字符串进行解码 | `urllib.parse.unquote(encoded_string)` | + +### 解析和构建URL + +```python +from urllib.parse import urlparse, urlunparse, urlsplit, urlunsplit, urljoin + +# 解析URL并返回ParseResult对象 +parsed_url = urlparse('http://www.example.com/path?query=arg') + +# 将ParseResult对象转换回URL +new_url = urlunparse(parsed_url) + +# 类似于urlparse(),但不分割params +split_result = urlsplit('http://www.example.com/path?query=arg') + +# 将由urlsplit()返回的对象转换回URL +original_url = urlunsplit(split_result) + +# 合并两个URL +new_url = urljoin('http://www.example.com/path/', '/anotherpath.html') + +``` + +### 转换查询字符串 + +```python +from urllib.parse import urlencode + +# 将字典或序列转换为URL查询字符串 +query_dict = {'key1': 'value1', 'key2': 'value2'} +query_string = urlencode(query_dict) + +``` + +### URL编码和解码 + +```python +from urllib.parse import quote, unquote + +# 将字符串进行URL编码 +encoded = quote('a string with / and ?') + +# 对URL编码的字符串进行解码 +decoded = unquote(encoded) +``` + +## `urllib.robotparser` + +通过使用 `urllib.robotparser`,你可以确保你的网络爬虫**尊重网站的抓取策略,这是一种负责任的爬虫行为。** + +| 方法 | 功能描述 | 示例 | +| ------------------- | ------------------------------------------------------ | -------------------------------------------------- | +| `RobotFileParser()` | 创建一个 `RobotFileParser` 对象 | `rp = urllib.robotparser.RobotFileParser()` | +| `set_url()` | 设置 `robots.txt` 文件的 URL | `rp.set_url('http://www.example.com/robots.txt')` | +| `read()` | 从设置的 URL 读取 `robots.txt` 文件 | `rp.read()` | +| `parse()` | 用于手动解析 `robots.txt` 文件的行 | `rp.parse(robots_txt_body.split("\n"))` | +| `can_fetch()` | 检查指定的 User-Agent 是否可以访问某个路径 | `rp.can_fetch('*', 'http://www.example.com/page')` | +| `mtime()` | 获取最后一次获取 `robots.txt` 文件的时间(Unix时间戳) | `rp.mtime()` | +| `modified()` | 设置最后一次获取 `robots.txt` 文件的时间 | `rp.modified()` | + +### 创建和设置 RobotFileParser + +首先,你需要创建一个 `RobotFileParser` 对象,并设置要解析的 `robots.txt` 文件的 URL。 + +```python +import urllib.robotparser + +# 创建 RobotFileParser 对象 +rp = urllib.robotparser.RobotFileParser() + +# 设置 robots.txt 文件的 URL +rp.set_url('http://www.example.com/robots.txt') + +# 从 URL 读取 robots.txt 文件 +rp.read() +``` + +### 检查爬虫是否可以访问特定页面 + +使用 `can_fetch()` 方法,您可以检查指定的 User-Agent 是否被允许抓取特定的网页路径。 + +```python +# 检查 '*'(所有 User-Agents)是否允许访问 '/page' +allowed = rp.can_fetch('*', 'http://www.example.com/page') + +if allowed: + print("I can crawl this page.") +else: + print("I cannot crawl this page.") +``` + +### 手动解析 robots.txt + +如果你需要手动解析 `robots.txt` 文件的内容,可以使用 `parse()` 方法。 + +```python +# 假设 robots_txt_body 包含了 robots.txt 的文本内容 +robots_txt_body = ''' +User-agent: * +Disallow: /private/ +''' + +# 手动解析这些规则 +rp.parse(robots_txt_body.split("\n")) +``` diff --git a/wiki/programming-language/Python/进阶/标准库/通用操作系统服务/os --- 多种操作系统接口.md b/wiki/programming-language/Python/进阶/标准库/通用操作系统服务/os 多种操作系统接口.md similarity index 86% rename from wiki/programming-language/Python/进阶/标准库/通用操作系统服务/os --- 多种操作系统接口.md rename to wiki/programming-language/Python/进阶/标准库/通用操作系统服务/os 多种操作系统接口.md index a9707e77..cd3b7f8c 100644 --- a/wiki/programming-language/Python/进阶/标准库/通用操作系统服务/os --- 多种操作系统接口.md +++ b/wiki/programming-language/Python/进阶/标准库/通用操作系统服务/os 多种操作系统接口.md @@ -1,6 +1,6 @@ --- -title: os --- 多种操作系统接口 -description: os --- 多种操作系统接口 +title: os 多种操作系统接口 +description: os 多种操作系统接口 keywords: - python - os @@ -13,9 +13,26 @@ author: 7Wate date: 2023-08-04 --- -在进行 Python 编程时,与操作系统进行交互是常见的需求。这包括但不限于管理文件系统、获取系统信息、处理路径等。Python 的 `os` 模块作为标准库的一部分,提供了丰富的方法来完成这些任务。下面是一些主要功能和使用示例。 +## 概述 -## 模块导入 +**`os` 模块的主要目的之一就是提供一个跨平台的接口来与操作系统进行交互。**通过这个抽象层,开发者可以编写在多种操作系统上都能运行的代码,而无需关心底层操作系统的具体实现细节。 + +这样做有几个主要优点: + +1. **可移植性**:代码可以在不同的操作系统上运行,无需进行大量的修改。 +2. **维护性**:由于操作系统特定的实现细节被抽象出来,维护代码变得更容易。 +3. **可读性和可理解性**:提供了一组统一的 API,使得代码更容易阅读和理解。 +4. **开发效率**:开发者可以更快地开发应用程序,因为他们不需要了解所有操作系统的内部工作机制。 + +然而,也有一些局限性和挑战: + +1. **性能**:抽象层可能会引入一些额外的性能开销。 +2. **功能限制**:为了保持跨平台性,`os` 模块可能不会提供某个特定操作系统上可用的高级功能。 +3. **平台特定的代码**:虽然 `os` 模块尽量提供跨平台的方法,但有时还是需要编写一些平台特定的代码。 + +**总体来说,`os` 模块确实旨在消除操作系统之间的不一致性,并提供一个更加统一和高级的编程接口。** + +## 导入 ```python import os