1
0

Python:urllib 处理模块

This commit is contained in:
周中平 2023-08-29 14:37:11 +08:00
parent 8286202c6d
commit 2a7f862377
Signed by: zhouzhongping
GPG Key ID: 6666822800008000
3 changed files with 352 additions and 6 deletions

View File

@ -1,8 +1,8 @@
{ {
"label": "第三方模块", "label": "拓展模块",
"position": 3, "position": 3,
"link": { "link": {
"type": "generated-index", "type": "generated-index",
"title": "第三方模块" "title": "拓展模块"
} }
} }

View File

@ -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"))
```

View File

@ -1,6 +1,6 @@
--- ---
title: os --- 多种操作系统接口 title: os 多种操作系统接口
description: os --- 多种操作系统接口 description: os 多种操作系统接口
keywords: keywords:
- python - python
- os - os
@ -13,9 +13,26 @@ author: 7Wate
date: 2023-08-04 date: 2023-08-04
--- ---
在进行 Python 编程时与操作系统进行交互是常见的需求。这包括但不限于管理文件系统、获取系统信息、处理路径等。Python 的 `os` 模块作为标准库的一部分,提供了丰富的方法来完成这些任务。下面是一些主要功能和使用示例。 ## 概述
## 模块导入 **`os` 模块的主要目的之一就是提供一个跨平台的接口来与操作系统进行交互。**通过这个抽象层,开发者可以编写在多种操作系统上都能运行的代码,而无需关心底层操作系统的具体实现细节。
这样做有几个主要优点:
1. **可移植性**:代码可以在不同的操作系统上运行,无需进行大量的修改。
2. **维护性**:由于操作系统特定的实现细节被抽象出来,维护代码变得更容易。
3. **可读性和可理解性**:提供了一组统一的 API使得代码更容易阅读和理解。
4. **开发效率**:开发者可以更快地开发应用程序,因为他们不需要了解所有操作系统的内部工作机制。
然而,也有一些局限性和挑战:
1. **性能**:抽象层可能会引入一些额外的性能开销。
2. **功能限制**:为了保持跨平台性,`os` 模块可能不会提供某个特定操作系统上可用的高级功能。
3. **平台特定的代码**:虽然 `os` 模块尽量提供跨平台的方法,但有时还是需要编写一些平台特定的代码。
**总体来说,`os` 模块确实旨在消除操作系统之间的不一致性,并提供一个更加统一和高级的编程接口。**
## 导入
```python ```python
import os import os