导航菜单

  • 1.vector
  • 2.milvus
  • 3.pymilvus
  • 4.rag
  • 5.rag_measure
  • ragflow
  • heapq
  • HNSW
  • cosine_similarity
  • math
  • typing
  • etcd
  • minio
  • collections
  • jieba
  • random
  • beautifulsoup4
  • chromadb
  • sentence_transformers
  • numpy
  • lxml
  • openpyxl
  • PyMuPDF
  • python-docx
  • requests
  • python-pptx
  • text_splitter
  • all-MiniLM-L6-v2
  • openai
  • llm
  • BPETokenizer
  • Flask
  • RAGAS
  • BagofWords
  • langchain
  • Pydantic
  • abc
  • faiss
  • MMR
  • scikit-learn
  • Runnable
  • PromptEngineering
  • dataclasses
  • LaTeX
  • rank_bm25
  • TF-IDF
  • asyncio
  • sqlalchemy
  • fastapi
  • Starlette
  • uvicorn
  • argparse
  • Generic
  • ssl
  • urllib
  • python-dotenv
  • RRF
  • CrossEncoder
  • Lost-in-the-middle
  • Jinja2
  • logger
  • io
  • venv
  • concurrent
  • parameter
  • SSE
  • 1. urllib 是什么?
    • 1.1 为什么需要 urllib?
    • 1.2 urllib 模块结构
  • 2. 前置知识
    • 2.1 HTTP 基础知识
    • 2.2 URL 结构
    • 2.3 Python 基础
  • 3. urllib.request:发送 HTTP 请求
    • 3.1 基本 GET 请求
    • 3.2 使用 with 语句(推荐)
    • 3.3 带查询参数的 GET 请求
    • 3.4 POST 请求:发送表单数据
    • 3.5 POST 请求:发送 JSON 数据
    • 3.6 设置请求头
    • 3.7 处理超时
  • 4. urllib.parse:解析和构建 URL
    • 4.1 解析 URL
    • 4.2 构建 URL
    • 4.3 处理查询参数
    • 4.4 URL 编码和解码
  • 5. urllib.error:异常处理
  • 6. 实际应用示例
    • 6.1 下载文件
    • 6.2 简单的 API 客户端
    • 6.3 带基本认证的请求
  • 7. 常见问题
    • 7.1 urllib 和 requests 的区别?
    • 7.2 如何处理 SSL 证书错误?
    • 7.3 如何设置 Cookie?
  • 8. 总结
    • 8.1 核心概念回顾
    • 8.2 使用 urllib 的好处

1. urllib 是什么? #

urllib 是 Python 的标准库,用于处理 URL(统一资源定位符)相关的操作,包括发送 HTTP 请求、解析 URL、处理响应等。它是 Python 内置的,无需额外安装。

1.1 为什么需要 urllib? #

在 Web 开发中,经常需要:

  • 从网站获取数据(如 API 调用)
  • 下载文件
  • 解析和处理 URL
  • 发送 HTTP 请求

urllib 的优势:

  1. 无需安装:Python 内置,开箱即用
  2. 学习价值高:帮助理解 HTTP 协议原理
  3. 功能完整:满足基本的网络请求需求
  4. 可控性强:可以精细控制请求过程

简单理解:

  • urllib:Python 自带的网络请求工具
  • requests:第三方库,更简单易用(需要安装)

1.2 urllib 模块结构 #

urllib 包含多个子模块,每个模块负责不同的功能:

# 导入 urllib 的各个子模块
import urllib.request    # 发送 HTTP 请求(最常用)
import urllib.parse      # 解析和构建 URL
import urllib.error      # 异常处理
import urllib.response   # 响应处理(通常不需要直接导入)

主要模块说明:

  • urllib.request:发送 HTTP 请求,获取响应
  • urllib.parse:解析 URL,处理查询参数
  • urllib.error:处理网络请求中的异常
  • urllib.response:响应对象(通常通过 urlopen 返回)

2. 前置知识 #

在学习 urllib 之前,你需要了解以下基础知识。

2.1 HTTP 基础知识 #

HTTP(HyperText Transfer Protocol) 是 Web 上最常用的协议,用于在客户端和服务器之间传输数据。

HTTP 请求方法:

  • GET:获取数据(如查看网页、获取 API 数据)
  • POST:提交数据(如登录、创建资源)
  • PUT:更新数据
  • DELETE:删除数据

HTTP 状态码:

  • 200:成功
  • 404:资源不存在
  • 500:服务器错误

2.2 URL 结构 #

URL(Uniform Resource Locator) 是网页地址,由多个部分组成:

https://www.example.com:8080/path/to/page?name=value#fragment
│      │                  │    │              │         │
│      │                  │    │              │         └─ 锚点(页面内跳转)
│      │                  │    │              └─ 查询参数
│      │                  │    └─ 路径
│      │                  └─ 端口号
│      └─ 域名
└─ 协议(http/https)

简单理解:

  • 协议:http:// 或 https://(安全)
  • 域名:网站地址,如 www.example.com
  • 路径:具体页面路径,如 /users/profile
  • 查询参数:?key=value&key2=value2,用于传递数据

2.3 Python 基础 #

你需要了解:

  • 基本的 Python 语法
  • 异常处理(try/except)
  • 文件操作(读取、写入)
  • 字符串编码(utf-8)

3. urllib.request:发送 HTTP 请求 #

urllib.request 是最常用的模块,用于发送 HTTP 请求并获取响应。

3.1 基本 GET 请求 #

GET 请求用于获取数据,是最简单的请求方式。

# 导入 urllib.request 模块
import urllib.request

# 发送 GET 请求
# urlopen() 函数用于打开 URL 并返回响应对象
response = urllib.request.urlopen('https://www.example.com')

# 读取响应内容(返回字节数据)
content = response.read()

# 将字节数据解码为字符串(使用 utf-8 编码)
html = content.decode('utf-8')

# 打印响应内容
print(html)

# 获取响应状态码(200 表示成功)
print(f"状态码:{response.status}")

# 获取所有响应头(字典格式)
headers = response.getheaders()
print(f"响应头:{headers}")

# 获取特定响应头(如 Content-Type)
content_type = response.getheader('Content-Type')
print(f"内容类型:{content_type}")

# 关闭响应(使用 with 语句会自动关闭)
response.close()

说明:

  • urlopen() 发送 GET 请求并返回响应对象
  • response.read() 读取响应内容(字节数据)
  • decode('utf-8') 将字节数据转换为字符串
  • response.status 获取 HTTP 状态码
  • response.getheader() 获取特定响应头

3.2 使用 with 语句(推荐) #

使用 with 语句可以自动关闭响应,更安全。

# 导入 urllib.request 模块
import urllib.request

# 使用 with 语句自动管理资源
# 请求完成后会自动关闭连接
with urllib.request.urlopen('https://www.example.com') as response:
    # 读取响应内容
    content = response.read()

    # 解码为字符串
    html = content.decode('utf-8')

    # 打印前 200 个字符
    print(html[:200])

    # 获取状态码
    print(f"状态码:{response.status}")

3.3 带查询参数的 GET 请求 #

在实际应用中,经常需要在 URL 中添加查询参数(如搜索关键词、分页参数等)。

# 导入 urllib.request 和 urllib.parse 模块
import urllib.request
import urllib.parse

# 定义查询参数(字典格式)
params = {
    'q': 'Python教程',  # 搜索关键词
    'page': 1,          # 页码
    'limit': 10         # 每页数量
}

# 使用 urlencode() 将字典编码为 URL 查询字符串
# 会自动处理中文字符编码
query_string = urllib.parse.urlencode(params)

# 构建完整的 URL
# httpbin.org 是一个用于测试 HTTP 请求的网站
url = f'https://httpbin.org/get?{query_string}'

# 发送 GET 请求
with urllib.request.urlopen(url) as response:
    # 读取响应内容
    data = response.read()

    # 解码为字符串
    result = data.decode('utf-8')

    # 打印响应(JSON 格式)
    print(result)

说明:

  • urlencode() 将字典转换为 URL 查询字符串
  • 会自动处理中文字符的编码(如 Python教程 会被编码为 Python%E6%95%99%E7%A8%8B)
  • httpbin.org 是一个测试网站,会返回请求的详细信息

3.4 POST 请求:发送表单数据 #

POST 请求用于提交数据,如登录、注册等。

# 导入必要的模块
import urllib.request
import urllib.parse

# 定义表单数据(字典格式)
form_data = {
    'username': 'admin',
    'password': '123456'
}

# 将表单数据编码为 URL 格式
# urlencode() 返回字符串,需要编码为字节
encoded_data = urllib.parse.urlencode(form_data).encode('utf-8')

# 创建请求对象
# Request() 用于创建更复杂的请求(可以设置方法、数据、请求头等)
req = urllib.request.Request(
    'https://httpbin.org/post',  # 请求的 URL
    data=encoded_data,            # POST 数据(必须是字节)
    method='POST'                 # 请求方法
)

# 发送请求
with urllib.request.urlopen(req) as response:
    # 读取响应
    result = response.read().decode('utf-8')
    print(result)

说明:

  • POST 请求需要提供 data 参数(必须是字节数据)
  • urlencode().encode('utf-8') 将字典转换为字节数据
  • Request() 用于创建更复杂的请求对象
  • method='POST' 指定请求方法

3.5 POST 请求:发送 JSON 数据 #

很多 API 使用 JSON 格式传输数据。

# 导入必要的模块
import urllib.request
import urllib.parse
import json

# 定义 JSON 数据(字典格式)
json_data = {
    'name': '张三',
    'age': 25
}

# 将字典转换为 JSON 字符串,然后编码为字节
# json.dumps() 将 Python 对象转换为 JSON 字符串
# encode('utf-8') 将字符串编码为字节
json_bytes = json.dumps(json_data).encode('utf-8')

# 创建请求对象
req = urllib.request.Request(
    'https://httpbin.org/post',  # 请求的 URL
    data=json_bytes,              # JSON 数据(字节格式)
    headers={
        'Content-Type': 'application/json'  # 设置请求头,告诉服务器这是 JSON 数据
    },
    method='POST'                 # 请求方法
)

# 发送请求
with urllib.request.urlopen(req) as response:
    # 读取响应
    result = response.read().decode('utf-8')
    print(result)

说明:

  • json.dumps() 将 Python 字典转换为 JSON 字符串
  • Content-Type: application/json 告诉服务器这是 JSON 数据
  • JSON 数据也需要编码为字节

3.6 设置请求头 #

请求头(Headers)用于传递额外的信息,如用户代理、认证信息等。

# 导入 urllib.request 模块
import urllib.request

# 定义自定义请求头(字典格式)
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    # User-Agent 告诉服务器你使用的浏览器/客户端
    'Accept': 'application/json',
    # Accept 告诉服务器你希望接收的数据类型
    'Authorization': 'Bearer token123'
    # Authorization 用于身份认证(Bearer token 是常见的认证方式)
}

# 创建请求对象,设置请求头
req = urllib.request.Request(
    'https://httpbin.org/headers',  # 请求的 URL
    headers=headers                 # 设置请求头
)

# 发送请求
with urllib.request.urlopen(req) as response:
    # 读取响应
    result = response.read().decode('utf-8')
    print(result)

说明:

  • User-Agent 标识客户端类型(有些网站会检查这个)
  • Accept 指定希望接收的内容类型
  • Authorization 用于身份认证(Bearer token 是常见方式)

3.7 处理超时 #

网络请求可能会因为网络问题而超时,需要设置超时时间。

# 导入 urllib.request 和 urllib.error 模块
import urllib.request
import urllib.error

# 设置超时时间(秒)
# timeout=5 表示如果 5 秒内没有响应,就抛出异常
try:
    with urllib.request.urlopen('https://www.example.com', timeout=5) as response:
        content = response.read().decode('utf-8')
        print("请求成功")
        print(content[:100])  # 打印前 100 个字符
except urllib.error.URLError as e:
    # 捕获 URL 错误(包括超时)
    print(f"请求失败:{e.reason}")

说明:

  • timeout=5 设置超时时间为 5 秒
  • 如果超时,会抛出 URLError 异常
  • 使用 try/except 处理异常

4. urllib.parse:解析和构建 URL #

urllib.parse 用于解析 URL、处理查询参数、编码/解码等。

4.1 解析 URL #

urlparse() 可以将 URL 分解为各个组成部分。

# 导入 urllib.parse 模块
from urllib.parse import urlparse

# 解析 URL
# urlparse() 将 URL 分解为多个组成部分
result = urlparse('https://www.example.com:8080/path/to/page?name=value#fragment')

# 打印各个组成部分
print(f"协议(scheme):{result.scheme}")        # https
print(f"网络位置(netloc):{result.netloc}")    # www.example.com:8080
print(f"路径(path):{result.path}")            # /path/to/page
print(f"查询参数(query):{result.query}")      # name=value
print(f"锚点(fragment):{result.fragment}")    # fragment
print(f"用户名(username):{result.username}")  # None(如果没有)
print(f"密码(password):{result.password}")    # None(如果没有)
print(f"主机名(hostname):{result.hostname}")   # www.example.com
print(f"端口号(port):{result.port}")           # 8080

说明:

  • urlparse() 返回一个 ParseResult 对象
  • 可以访问 URL 的各个组成部分
  • 常用于提取 URL 中的信息

4.2 构建 URL #

urlunparse() 可以将各个部分组合成完整的 URL。

# 导入 urllib.parse 模块
from urllib.parse import urlunparse

# 构建 URL
# urlunparse() 接受一个包含 6 个元素的元组
# 格式:(scheme, netloc, path, params, query, fragment)
url = urlunparse((
    'https',              # 协议
    'www.example.com',    # 网络位置(域名)
    '/path',              # 路径
    '',                   # 参数(通常为空)
    'name=value',         # 查询参数
    'fragment'            # 锚点
))

# 打印构建的 URL
print(url)  # https://www.example.com/path?name=value#fragment

4.3 处理查询参数 #

urlencode() 用于将字典编码为查询字符串,parse_qs() 用于解析查询字符串。

# 导入 urllib.parse 模块
from urllib.parse import urlencode, parse_qs, parse_qsl

# 编码查询参数(字典 → 查询字符串)
params = {
    'q': 'Python教程',  # 搜索关键词
    'page': 1,          # 页码
    'sort': 'recent'    # 排序方式
}

# urlencode() 将字典转换为 URL 查询字符串
# 会自动处理中文字符编码
query_string = urlencode(params)
print(f"编码后的查询字符串:{query_string}")
# 输出:q=Python%E6%95%99%E7%A8%8B&page=1&sort=recent

# 解析查询字符串(查询字符串 → 字典)
# parse_qs() 返回字典,值是列表(因为一个参数可能有多个值)
query_str = 'name=张三&age=25&hobbies=编程&hobbies=读书'
parsed_dict = parse_qs(query_str)
print(f"解析为字典:{parsed_dict}")
# 输出:{'name': ['张三'], 'age': ['25'], 'hobbies': ['编程', '读书']}

# parse_qsl() 返回列表,每个元素是 (键, 值) 的元组
parsed_list = parse_qsl(query_str)
print(f"解析为列表:{parsed_list}")
# 输出:[('name', '张三'), ('age', '25'), ('hobbies', '编程'), ('hobbies', '读书')]

说明:

  • urlencode() 将字典编码为查询字符串
  • parse_qs() 返回字典(值是列表,因为一个参数可能有多个值)
  • parse_qsl() 返回列表(每个元素是键值对元组)

4.4 URL 编码和解码 #

URL 中不能直接使用某些字符(如中文、空格),需要编码。

# 导入 urllib.parse 模块
from urllib.parse import quote, unquote, quote_plus, unquote_plus

# 编码 URL(将特殊字符转换为 %XX 格式)
# quote() 用于编码 URL 中的特殊字符
text = 'Python 教程'
encoded = quote(text)
print(f"编码后:{encoded}")
# 输出:Python%20%E6%95%99%E7%A8%8B
# %20 是空格的编码,%E6%95%99%E7%A8%8B 是"教程"的编码

# 构建完整的 URL
url = f'https://www.example.com/search?q={encoded}'
print(f"完整 URL:{url}")

# 解码 URL(将 %XX 格式转换回原始字符)
decoded = unquote(encoded)
print(f"解码后:{decoded}")
# 输出:Python 教程

# quote_plus() 会将空格转换为 +(而不是 %20)
url2 = f'https://www.example.com/search?q={quote_plus(text)}'
print(f"使用 quote_plus:{url2}")
# 输出:https://www.example.com/search?q=Python+%E6%95%99%E7%A8%8B

# unquote_plus() 会将 + 转换回空格
decoded2 = unquote_plus('Python+%E6%95%99%E7%A8%8B')
print(f"解码 plus 编码:{decoded2}")
# 输出:Python 教程

说明:

  • quote() 编码 URL(空格变为 %20)
  • quote_plus() 编码 URL(空格变为 +)
  • unquote() 和 unquote_plus() 用于解码

5. urllib.error:异常处理 #

网络请求可能会失败,需要处理各种异常。

# 导入必要的模块
import urllib.request
import urllib.error

# 尝试发送请求
try:
    # 发送请求(这个 URL 会返回 404 错误)
    with urllib.request.urlopen('https://httpbin.org/status/404') as response:
        content = response.read()
        print("请求成功")
except urllib.error.HTTPError as e:
    # 捕获 HTTP 错误(如 404、500 等)
    print(f"HTTP 错误:{e.code} - {e.reason}")
    # e.code 是状态码(如 404)
    # e.reason 是错误原因(如 Not Found)
    print(f"响应头:{e.headers}")
    # e.headers 是响应头(字典格式)
except urllib.error.URLError as e:
    # 捕获 URL 错误(如网络错误、超时等)
    print(f"URL 错误:{e.reason}")
    # e.reason 是错误原因
else:
    # 如果没有异常,执行这里
    print("请求成功")

说明:

  • HTTPError:HTTP 错误(如 404、500)
  • URLError:URL 错误(如网络错误、超时)
  • HTTPError 是 URLError 的子类,所以先捕获 HTTPError

6. 实际应用示例 #

6.1 下载文件 #

使用 urlretrieve() 可以方便地下载文件。

# 导入必要的模块
import urllib.request
import os

# 定义下载文件的函数
def download_file(url, save_path):
    """下载文件到指定路径"""
    try:
        # 创建保存目录(如果不存在)
        # os.path.dirname() 获取目录路径
        # os.makedirs() 创建目录(exist_ok=True 表示如果已存在不报错)
        os.makedirs(os.path.dirname(save_path), exist_ok=True)

        # 下载文件
        # urlretrieve() 直接下载文件到本地
        urllib.request.urlretrieve(url, save_path)

        # 打印成功信息
        print(f'文件下载成功:{save_path}')
    except Exception as e:
        # 捕获所有异常
        print(f'下载失败:{e}')

# 主程序入口
if __name__ == "__main__":
    # 下载文件示例
    # 注意:这个 URL 可能不存在,仅作为示例
    download_file(
        'https://www.example.com/image.jpg',
        './downloads/image.jpg'
    )

说明:

  • urlretrieve() 直接下载文件到本地
  • os.makedirs() 创建目录
  • 使用 try/except 处理异常

6.2 简单的 API 客户端 #

创建一个简单的 API 客户端类,封装常用的请求操作。

# 导入必要的模块
import urllib.request
import urllib.parse
import urllib.error
import json

# 定义 API 客户端类
class APIClient:
    """简单的 API 客户端"""

    def __init__(self, base_url: str, api_key: str = None):
        # 初始化方法
        # base_url: API 的基础 URL(如 https://api.example.com)
        # api_key: API 密钥(可选)

        # 移除 base_url 末尾的斜杠(如果有)
        self.base_url = base_url.rstrip('/')

        # 保存 API 密钥
        self.api_key = api_key

        # 设置默认请求头
        self.headers = {
            'User-Agent': 'APIClient/1.0',      # 用户代理
            'Accept': 'application/json'         # 接受 JSON 格式
        }

        # 如果有 API 密钥,添加到请求头
        if api_key:
            self.headers['Authorization'] = f'Bearer {api_key}'

    def get(self, endpoint: str, params: dict = None):
        """发送 GET 请求"""
        # endpoint: API 端点(如 /users)
        # params: 查询参数(可选)

        # 构建完整的 URL
        # lstrip('/') 移除 endpoint 开头的斜杠(如果有)
        url = f'{self.base_url}/{endpoint.lstrip("/")}'

        # 如果有查询参数,添加到 URL
        if params:
            query_string = urllib.parse.urlencode(params)
            url = f'{url}?{query_string}'

        # 创建请求对象
        req = urllib.request.Request(url, headers=self.headers)

        # 发送请求
        try:
            with urllib.request.urlopen(req) as response:
                # 读取响应并解析为 JSON
                data = response.read().decode('utf-8')
                return json.loads(data)
        except urllib.error.HTTPError as e:
            # 处理 HTTP 错误
            print(f"HTTP 错误:{e.code} - {e.reason}")
            return None
        except urllib.error.URLError as e:
            # 处理 URL 错误
            print(f"URL 错误:{e.reason}")
            return None

    def post(self, endpoint: str, data: dict):
        """发送 POST 请求"""
        # endpoint: API 端点
        # data: 要发送的数据(字典格式)

        # 构建完整的 URL
        url = f'{self.base_url}/{endpoint.lstrip("/")}'

        # 将数据转换为 JSON 字符串,然后编码为字节
        json_data = json.dumps(data).encode('utf-8')

        # 设置 Content-Type 请求头
        self.headers['Content-Type'] = 'application/json'

        # 创建请求对象
        req = urllib.request.Request(
            url,
            data=json_data,
            headers=self.headers,
            method='POST'
        )

        # 发送请求
        try:
            with urllib.request.urlopen(req) as response:
                # 读取响应并解析为 JSON
                result = response.read().decode('utf-8')
                return json.loads(result)
        except urllib.error.HTTPError as e:
            # 处理 HTTP 错误
            print(f"HTTP 错误:{e.code} - {e.reason}")
            return None
        except urllib.error.URLError as e:
            # 处理 URL 错误
            print(f"URL 错误:{e.reason}")
            return None

# 主程序入口
if __name__ == "__main__":
    # 创建 API 客户端实例
    # jsonplaceholder.typicode.com 是一个用于测试的 API 服务
    client = APIClient('https://jsonplaceholder.typicode.com')

    # 发送 GET 请求
    # 获取用户 ID 为 1 的所有文章
    posts = client.get('/posts', {'userId': 1})
    if posts:
        print(f'获取到 {len(posts)} 篇文章')
        if posts:
            print(f'第一篇文章标题:{posts[0]["title"]}')

    # 发送 POST 请求
    # 创建新文章
    new_post = client.post('/posts', {
        'title': '测试标题',
        'body': '测试内容',
        'userId': 1
    })
    if new_post:
        print(f'创建新文章,ID: {new_post["id"]}')

说明:

  • APIClient 类封装了常用的 API 请求操作
  • get() 方法发送 GET 请求
  • post() 方法发送 POST 请求
  • 使用 try/except 处理异常

6.3 带基本认证的请求 #

有些 API 需要基本认证(Basic Authentication)。

# 导入必要的模块
import urllib.request
import urllib.error
import base64

# 定义带基本认证的请求函数
def basic_auth_request(url, username, password):
    """发送带基本认证的请求"""
    # url: 请求的 URL
    # username: 用户名
    # password: 密码

    # 创建认证字符串(格式:username:password)
    auth_str = f'{username}:{password}'

    # 将字符串编码为字节
    auth_bytes = auth_str.encode('utf-8')

    # 使用 base64 编码
    # base64.b64encode() 将字节编码为 base64 字符串
    auth_base64 = base64.b64encode(auth_bytes).decode('utf-8')

    # 设置请求头
    # Basic 认证格式:Authorization: Basic base64(username:password)
    headers = {
        'Authorization': f'Basic {auth_base64}',
        'User-Agent': 'MyApp/1.0'
    }

    # 创建请求对象
    req = urllib.request.Request(url, headers=headers)

    # 发送请求
    try:
        with urllib.request.urlopen(req) as response:
            # 读取响应
            return response.read().decode('utf-8')
    except urllib.error.HTTPError as e:
        # 处理 HTTP 错误
        return f'错误:{e.code} - {e.reason}'

# 主程序入口
if __name__ == "__main__":
    # 发送带基本认证的请求
    # httpbin.org 是一个测试网站,这个端点需要基本认证
    result = basic_auth_request(
        'https://httpbin.org/basic-auth/user/passwd',
        'user',      # 用户名
        'passwd'     # 密码
    )
    print(result)

说明:

  • 基本认证需要将 username:password 进行 base64 编码
  • 格式:Authorization: Basic base64(username:password)
  • base64.b64encode() 用于 base64 编码

7. 常见问题 #

7.1 urllib 和 requests 的区别? #

特性 urllib requests
安装 Python 内置 需要单独安装
易用性 较复杂 非常简单
功能 基础功能 功能丰富
文档 官方文档 优秀文档

建议:

  • 学习 HTTP 原理:使用 urllib
  • 快速开发:使用 requests
  • 依赖最小化:使用 urllib(无需安装)
  • 生产环境:推荐 requests(更简单、功能更丰富)

7.2 如何处理 SSL 证书错误? #

如果遇到 SSL 证书错误,可以创建不验证证书的上下文(仅用于测试,生产环境不推荐)。

# 导入必要的模块
import urllib.request
import ssl

# 创建不验证证书的 SSL 上下文(仅用于测试)
# 生产环境应该使用有效的证书
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE

# 使用自定义的 SSL 上下文发送请求
with urllib.request.urlopen(
    'https://www.example.com',
    context=ssl_context
) as response:
    content = response.read().decode('utf-8')
    print(content[:100])

注意:不验证证书存在安全风险,仅用于测试环境。

7.3 如何设置 Cookie? #

使用 http.cookiejar 可以处理 Cookie。

# 导入必要的模块
import urllib.request
import http.cookiejar

# 创建 CookieJar(用于存储 Cookie)
cookie_jar = http.cookiejar.CookieJar()

# 创建 Cookie 处理器
cookie_handler = urllib.request.HTTPCookieProcessor(cookie_jar)

# 创建 opener(用于发送请求)
opener = urllib.request.build_opener(cookie_handler)

# 使用 opener 发送请求(会自动处理 Cookie)
response = opener.open('https://httpbin.org/cookies/set?name=value')

# 读取响应
print(response.read().decode('utf-8'))

# 查看 Cookie
for cookie in cookie_jar:
    print(f'{cookie.name} = {cookie.value}')

8. 总结 #

8.1 核心概念回顾 #

  • urllib.request:发送 HTTP 请求

    • urlopen():发送简单请求
    • Request():创建复杂请求
    • urlretrieve():下载文件
  • urllib.parse:解析和构建 URL

    • urlparse():解析 URL
    • urlencode():编码查询参数
    • quote():编码 URL 中的特殊字符
  • urllib.error:异常处理

    • HTTPError:HTTP 错误
    • URLError:URL 错误

8.2 使用 urllib 的好处 #

  1. 无需安装:Python 内置,开箱即用
  2. 学习价值高:帮助理解 HTTP 协议原理
  3. 功能完整:满足基本的网络请求需求
  4. 可控性强:可以精细控制请求过程
← 上一节 typing 下一节 uvicorn →

访问验证

请输入访问令牌

Token不正确,请重新输入