python urllib

Python原生请求库:urllib完全指南

什么是urllib?

urllib是Python标准库中的HTTP客户端模块,提供了一系列用于处理URL和进行网络请求的模块。它是Python内置的HTTP请求解决方案,无需安装第三方库即可使用。urllib包含以下几个子模块:

  • urllib.request - 打开和读取URL
  • urllib.error - 包含urllib.request引发的异常
  • urllib.parse - 解析URL
  • urllib.robotparser - 解析robots.txt文件

为什么使用urllib?

优势说明
无需安装Python标准库内置,开箱即用
轻量级不依赖第三方库,体积小
功能全面支持HTTP/HTTPS、FTP等多种协议
学习价值理解HTTP请求底层原理
兼容性好支持所有Python环境

基本HTTP请求

GET请求示例

from urllib.request import urlopen

# 基本GET请求
with urlopen('https://httpbin.org/get') as response:
    print(response.status)  # 200
    print(response.read().decode('utf-8'))  # 响应内容

代码解释:

  • urlopen()是最简单的发起请求的方法
  • 返回的对象类似文件对象,可以使用read()方法读取内容
  • 需要手动解码响应内容(通常为UTF-8)
  • 使用with语句确保连接正确关闭

带参数的GET请求

from urllib.request import urlopen
from urllib.parse import urlencode

# 构造查询参数
params = {'key1': 'value1', 'key2': 'value2'}
query_string = urlencode(params)
url = f'https://httpbin.org/get?{query_string}'

# 发送请求
with urlopen(url) as response:
    print(response.url)  # 完整URL
    print(response.read().decode('utf-8'))

代码解释:

  • urlencode()将字典转换为URL查询字符串
  • 手动拼接URL和查询参数
  • 适用于简单的GET请求

POST请求

表单数据POST

from urllib.request import Request, urlopen
from urllib.parse import urlencode

# 准备表单数据
data = urlencode({'key1': 'value1', 'key2': 'value2'}).encode('utf-8')

# 创建请求对象
request = Request(
    url='https://httpbin.org/post',
    data=data,
    method='POST'
)

# 发送请求
with urlopen(request) as response:
    print(response.status)  # 200
    print(response.read().decode('utf-8'))

代码解释:

  • Request类提供更灵活的请求配置
  • POST数据需要编码为bytes类型
  • 设置method参数为’POST’
  • 表单数据使用urlencode编码

JSON数据POST

from urllib.request import Request, urlopen
import json

# 准备JSON数据
data = json.dumps({'name': 'John', 'age': 30}).encode('utf-8')

# 创建请求对象并设置头部
request = Request(
    url='https://httpbin.org/post',
    data=data,
    method='POST',
    headers={'Content-Type': 'application/json'}
)

# 发送请求
with urlopen(request) as response:
    print(response.read().decode('utf-8'))

代码解释:

  • 使用json.dumps()将字典转换为JSON字符串
  • 必须设置Content-Typeapplication/json
  • 数据同样需要编码为bytes类型

高级功能

设置请求头

from urllib.request import Request, urlopen

# 自定义请求头
headers = {
    'User-Agent': 'Mozilla/5.0',
    'Accept': 'application/json',
    'X-Custom-Header': 'Value'
}

request = Request(
    url='https://httpbin.org/headers',
    headers=headers
)

with urlopen(request) as response:
    print(response.read().decode('utf-8'))

代码解释:

  • 通过headers参数设置自定义请求头
  • User-Agent可以伪装成浏览器访问
  • 服务端可以通过请求头返回不同内容

处理Cookies

from urllib.request import Request, urlopen, build_opener, HTTPCookieProcessor
from http.cookiejar import CookieJar

# 创建Cookie处理器
cookie_jar = CookieJar()
opener = build_opener(HTTPCookieProcessor(cookie_jar))

# 发送请求(自动处理Cookies)
request = Request('https://httpbin.org/cookies/set/sessioncookie/123456789')
response = opener.open(request)

# 查看Cookies
print([cookie.name for cookie in cookie_jar])

代码解释:

  • CookieJar用于存储Cookies
  • HTTPCookieProcessor自动处理Cookies
  • build_opener创建自定义opener
  • 适用于需要保持会话的场景

设置代理

from urllib.request import ProxyHandler, build_opener

# 设置代理
proxy_handler = ProxyHandler({
    'http': 'http://proxy.example.com:8080',
    'https': 'https://proxy.example.com:8080'
})

opener = build_opener(proxy_handler)

# 使用代理发送请求
response = opener.open('http://httpbin.org/ip')
print(response.read().decode('utf-8'))

代码解释:

  • ProxyHandler配置代理服务器
  • 支持HTTP和HTTPS代理
  • 需要构建自定义opener使用代理

错误处理

常见异常

异常描述
URLErrorURL相关错误的基类
HTTPErrorHTTP错误响应(如404, 500)
ContentTooShortError下载内容不完整

错误处理示例

from urllib.request import urlopen
from urllib.error import URLError, HTTPError

try:
    response = urlopen('https://example.com/nonexistent')
    print(response.read().decode('utf-8'))
except HTTPError as e:
    print(f'HTTP错误: {e.code} {e.reason}')
except URLError as e:
    print(f'URL错误: {e.reason}')
except Exception as e:
    print(f'其他错误: {e}')

代码解释:

  • HTTPError处理HTTP状态码错误
  • URLError处理网络连接等问题
  • 建议对不同类型错误分别处理

实用工具

URL解析

from urllib.parse import urlparse, urlunparse, urljoin

# 解析URL
result = urlparse('https://example.com/path;params?query=arg#frag')
print(result.scheme)    # https
print(result.netloc)    # example.com
print(result.path)      # /path
print(result.params)    # params
print(result.query)     # query=arg
print(result.fragment)  # frag

# 拼接URL
print(urljoin('https://example.com/path', 'subpath'))  # https://example.com/subpath

代码解释:

  • urlparse分解URL为6个组成部分
  • urlunparse执行反向操作
  • urljoin智能拼接URL

编码与解码

from urllib.parse import quote, unquote, quote_plus, unquote_plus

# URL编码
print(quote('上海'))      # %E4%B8%8A%E6%B5%B7
print(quote_plus('a b'))  # a+b

# URL解码
print(unquote('%E4%B8%8A%E6%B5%B7'))  # 上海
print(unquote_plus('a+b'))              # a b

代码解释:

  • quote对URL进行编码
  • quote_plus用+代替空格
  • unquoteunquote_plus执行反向操作

性能优化

复用连接

from urllib.request import OpenerDirector, HTTPHandler

# 创建自定义opener
opener = OpenerDirector()
opener.add_handler(HTTPHandler())

# 复用连接发送多个请求
for i in range(3):
    with opener.open('https://httpbin.org/get') as response:
        print(f'请求{i+1}:', response.status)

代码解释:

  • OpenerDirector管理多个处理器
  • HTTPHandler处理HTTP请求
  • 复用opener可以保持连接

总结

Python的urllib模块提供了完整的HTTP客户端功能,虽然不如第三方库如Requests简洁,但在以下场景特别有用:

  1. 无第三方依赖:受限环境无法安装第三方库
  2. 学习HTTP原理:理解底层HTTP通信机制
  3. 轻量级需求:简单请求不想引入额外依赖
  4. 标准库兼容:确保代码在所有Python环境运行

关键要点

  • urlopen适合简单请求
  • Request类提供更多控制
  • 使用urllib.parse处理URL
  • 自定义OpenerDirector实现高级功能
  • 注意错误处理和资源清理

与Requests对比

特性urllibRequests
安装内置需安装
易用性较低
功能基础丰富
性能较好优秀
社区支持一般强大

进一步学习

  • 官方文档:https://docs.python.org/3/library/urllib.html
  • 进阶教程:https://docs.python.org/3/howto/urllib2.html
  • 最佳实践:https://realpython.com/python-urllib-request/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王小玗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值