urllib模块 — URL处理

Python标准库精讲专题 · 网络通信篇 · 掌握URL处理工具

专题:Python标准库精讲系统学习

关键词:Python, 标准库, urllib, URL, HTTP请求, urlopen, urlparse, urlencode, quote, unquote

一、urllib概述

urllib是Python标准库中用于URL处理的模块集合,提供了一套完整的工具用于解析、构建、发送和操作URL。urllib涵盖从基本的URL解析到完整的HTTP请求发送、异常处理和爬虫协议支持等功能,是Python网络编程的基础组件之一。

urllib由四个核心子模块组成,各司其职又相互协作。urllib.request负责打开和读取URL,支持多种认证方式和代理设置;urllib.parse负责URL的解析、拆分、合并和编解码操作;urllib.error定义了请求过程中可能出现的异常类型;urllib.robotparser则提供了对robots.txt爬虫协议的解析能力。

理解urllib对于掌握Python网络编程至关重要。它不仅可以直接用于编写爬虫脚本、调用Web API,还是众多第三方网络库(如Requests)的基础。urllib的设计思想体现了Python"内置电池"的哲学,让开发者无需安装额外依赖即可完成常见的网络操作任务。

核心子模块概览

子模块功能说明常用类/函数
urllib.request打开和读取URLurlopen(), Request, OpenerDirector
urllib.parseURL解析与构建urlparse(), urlencode(), quote()
urllib.error异常处理URLError, HTTPError
urllib.robotparserrobots.txt解析RobotFileParser

urllib是Python官方推荐的URL处理标准库。虽然Requests等第三方库提供了更简洁的接口,但urllib作为内置库在零依赖场景下尤为重要,深入理解其原理有助于更好地使用上层库。

二、urllib.request

urllib.request是urllib包中最重要的子模块,提供了打开和读取URL的统一接口。其核心函数urlopen()可以像操作本地文件一样读取远程资源,同时支持GET、POST等HTTP方法,以及自定义请求头、Cookie、代理等高级功能。

urlopen()基本使用

urlopen()函数是访问URL的主要入口。对于简单场景,只需传入URL字符串即可返回一个类文件对象,通过read()方法读取响应内容。该函数返回的HTTPResponse对象封装了状态码、响应头和响应体等信息,可以像文件对象一样使用。

import urllib.request # 最简单的GET请求 response = urllib.request.urlopen('https://api.example.com/data') html = response.read().decode('utf-8') print(response.status) # 200 print(response.headers) # HTTP响应头

data参数 — 发送POST请求

urlopen()的data参数用于发送POST请求。当data参数被设置时,HTTP请求方法自动变为POST。data必须是字节流(bytes),通常需要使用urllib.parse.urlencode()将字典转换为编码后的查询字符串,再调用encode()转为字节。

import urllib.request import urllib.parse # 准备POST数据 post_data = {'username': 'admin', 'password': '123456'} data = urllib.parse.urlencode(post_data).encode('utf-8') # 发送POST请求 response = urllib.request.urlopen('https://httpbin.org/post', data=data) print(response.read().decode('utf-8'))

timeout参数 — 超时控制

timeout参数用于设置请求超时时间(秒)。在网络环境不稳定或目标服务器响应慢时,合理设置超时可以避免程序长时间阻塞。如果超过设定时间服务器仍未响应,将抛出socket.timeout异常。

import urllib.request # 设置10秒超时 try: response = urllib.request.urlopen( 'https://api.example.com', timeout=10 ) except urllib.error.URLError as e: print(f'请求超时或失败: {e.reason}')

Request类 — 自定义请求

Request类是构建HTTP请求的高级接口。相比直接使用urlopen(),Request类允许自定义请求方法(GET/POST/PUT/DELETE等)、添加请求头(Headers)、设置User-Agent、添加Cookie等。这种细粒度控制对于绕过反爬虫机制、访问需要特定请求头的API非常有用。

import urllib.request # 使用Request类构建自定义请求 req = urllib.request.Request( url='https://api.github.com/user', method='GET', headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', 'Accept': 'application/json', 'Authorization': 'Bearer YOUR_TOKEN' } ) response = urllib.request.urlopen(req) print(response.read().decode('utf-8'))

add_header()与get_header()

Request对象创建后仍然可以动态修改请求头。add_header()用于添加或更新单个请求头字段,get_header()则用于获取已设置的请求头值。这种按需调整的能力在实际开发中非常实用,比如在重试请求时修改User-Agent。

req = urllib.request.Request('https://httpbin.org/headers') # 动态添加请求头 req.add_header('User-Agent', 'CustomAgent/1.0') req.add_header('X-Custom-Header', 'my-value') # 获取请求头(注意需全小写) print(req.get_header('User-agent')) # CustomAgent/1.0

核心要点:urlopen()是请求入口,直接调用时自动使用GET方法;传入data参数切换为POST。Request类提供更完整的控制能力,是构建复杂请求的首选方式。合理设置timeout可防止程序挂起。使用add_header()灵活管理请求头。

三、urllib.parse

urllib.parse是URL解析和操作的核心工具集,提供了将URL拆分为组件、将组件重新组装为URL、以及处理URL中特殊字符编码的能力。无论是构建API请求参数,还是解析从Web页面中提取的链接,urllib.parse都是必不可少的工具。

urlparse() — URL解析

urlparse()函数将URL字符串解析为六个组成部分的命名元组:scheme(协议)、netloc(网络位置)、path(路径)、params(参数)、query(查询字符串)、fragment(片段标识符)。通过命名属性访问这些组件,可以轻松提取URL中的任意部分。

from urllib.parse import urlparse url = 'https://docs.python.org:8080/3/library/urllib.parse.html?highlight=urlparse#module-urllib.parse' parsed = urlparse(url) print(f'scheme : {parsed.scheme}') # https print(f'netloc : {parsed.netloc}') # docs.python.org:8080 print(f'path : {parsed.path}') # /3/library/urllib.parse.html print(f'params : {parsed.params}') # (空字符串) print(f'query : {parsed.query}') # highlight=urlparse print(f'fragment: {parsed.fragment}') # module-urllib.parse

urlsplit() — 简化版URL解析

urlsplit()与urlparse()功能类似,唯一的区别是urlsplit()不解析params参数(该参数在RFC 2396中已弃用)。在大多数现代应用中,params参数很少使用,因此urlsplit()是更常见的选择。它的返回结果只有5个组件,比urlparse()少一个。

from urllib.parse import urlsplit url = 'https://www.example.com/search?q=python&lang=zh' parts = urlsplit(url) print(parts.scheme) # https print(parts.netloc) # www.example.com print(parts.path) # /search print(parts.query) # q=python&lang=zh

urlunparse()与urlunsplit() — URL拼接

这两个函数是urlparse()和urlsplit()的逆操作,将元组形式的URL组件重新组合为完整的URL字符串。这在修改URL的某一部分(如替换查询参数或路径)后重新构建URL时非常有用。

from urllib.parse import urlunparse # 手动构建URL new_url = urlunparse(( 'https', # scheme 'api.example.com', # netloc '/v2/users', # path '', # params 'page=1&limit=20', # query '' # fragment )) print(new_url) # 输出: https://api.example.com/v2/users?page=1&limit=20

urlencode() — 查询参数编码

urlencode()是构建URL查询字符串的核心函数。它将字典或两元素元组列表转换为URL编码的查询字符串,自动处理特殊字符的转义。这是发送POST数据或构建GET请求URL时的必备工具。

from urllib.parse import urlencode params = { 'query': 'Python urllib', 'page': 2, 'lang': 'zh-CN', 'tags': ['network', 'url'] } # doseq=True 表示对序列参数重复键名 query_string = urlencode(params, doseq=True) print(query_string) # 输出: query=Python+urllib&page=2&lang=zh-CN&tags=network&tags=url

quote()与quote_plus() — URL编码

quote()和quote_plus()用于对URL中的特殊字符进行百分号编码(Percent-encoding)。quote()将空格编码为%20,而quote_plus()将空格编码为+(更符合application/x-www-form-urlencoded规范)。这些函数确保URL中的非ASCII字符和特殊字符被正确编码。

from urllib.parse import quote, quote_plus text = 'Python 编程 指南' print(quote(text)) # Python%20%E7%BC%96%E7%A8%8B%20%E6%8C%87%E5%8D%97 print(quote_plus(text)) # Python+%E7%BC%96%E7%A8%8B+%E6%8C%87%E5%8D%97 # safe参数指定不编码的字符 print(quote('/path/to/file', safe='/')) # /path/to/file

unquote()与unquote_plus() — URL解码

unquote()和unquote_plus()是quote()和quote_plus()的逆操作,将百分号编码的字符串还原为原始内容。在接收和解析URL参数时,必须进行解码才能得到原始数据。

from urllib.parse import unquote, unquote_plus encoded = 'Python+%E7%BC%96%E7%A8%8B+%E6%8C%87%E5%8D%97' print(unquote(encoded)) # Python+编程+指南(+号原样保留) print(unquote_plus(encoded)) # Python 编程 指南(+号变为空格)

parse_qs()与parse_qsl() — 查询字符串解析

parse_qs()将查询字符串解析为字典,相同键的值合并到列表中;parse_qsl()将其解析为键值对元组的列表。两者都自动处理URL编码解码,是逆向解析GET请求参数的理想工具。

from urllib.parse import parse_qs, parse_qsl query = 'name=John+Doe&age=30&hobby=reading&hobby=swimming' # 转为字典(值始终为列表) parsed_dict = parse_qs(query) print(parsed_dict) # {'name': ['John Doe'], 'age': ['30'], 'hobby': ['reading', 'swimming']} # 转为列表 parsed_list = parse_qsl(query) print(parsed_list) # [('name', 'John Doe'), ('age', '30'), ('hobby', 'reading'), ('hobby', 'swimming')]

核心要点:urllib.parse是URL处理的瑞士军刀。urlparse/urlsplit用于分解URL,urlunparse/urlunsplit用于重组URL。urlencode是构建查询参数的捷径。quote/quote_plus和unquote/unquote_plus处理字符编码。parse_qs/parse_qsl解析查询字符串。掌握这些工具可以轻松应对任何URL操作需求。

四、认证与Cookie

在实际网络编程中,经常会遇到需要身份认证或使用Cookie的场景。urllib.request提供了多种认证处理器(Handler),通过OpenerDirector机制可以构建自定义的opener对象,实现基本认证、摘要认证、代理认证以及Cookie管理等高级功能。

认证处理器

urllib支持HTTP基本认证(Basic Auth)和摘要认证(Digest Auth)。HTTPBasicAuthHandler用于处理服务器返回401状态码时的基本认证质询;HTTPDigestAuthHandler则处理更安全的摘要认证。两者都需要配合密码管理器使用,告诉urllib在遇到认证挑战时使用哪些凭据。

import urllib.request # 创建密码管理器 password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() password_mgr.add_password( realm=None, # None表示适用于所有领域 uri='https://api.example.com', # 目标URL user='myusername', passwd='mypassword' ) # 创建认证处理器 auth_handler = urllib.request.HTTPBasicAuthHandler(password_mgr) # 构建opener并安装为全局默认 opener = urllib.request.build_opener(auth_handler) urllib.request.install_opener(opener) # 后续所有urlopen调用自动携带认证信息 response = urllib.request.urlopen('https://api.example.com/private')

ProxyHandler — 代理设置

ProxyHandler用于配置HTTP和HTTPS代理。在需要隐藏真实IP、访问受限资源或进行网络调试时,代理功能不可或缺。可以通过环境变量系统代理,也可以在代码中显式指定代理地址。

import urllib.request # 设置代理处理器 proxy_handler = urllib.request.ProxyHandler({ 'http': 'http://proxy.example.com:8080', 'https': 'https://proxy.example.com:8443' }) # 不使用代理(覆盖环境变量) no_proxy_handler = urllib.request.ProxyHandler({}) opener = urllib.request.build_opener(proxy_handler) response = opener.open('https://httpbin.org/ip')

OpenerDirector — 构建器模式

OpenerDirector是urllib.request的设计核心,采用构建器(Builder)模式。build_opener()函数接受多个Handler参数,将它们组合为一个完整的HTTP客户端。可以同时添加认证处理器、代理处理器、Cookie处理器等多个处理器,实现高度自定义的HTTP行为。

import urllib.request import http.cookiejar # 创建Cookie Jar cookie_jar = http.cookiejar.CookieJar() cookie_handler = urllib.request.HTTPCookieProcessor(cookie_jar) # 创建代理处理器 proxy_handler = urllib.request.ProxyHandler({ 'http': 'http://proxy.example.com:8080' }) # 组合多个处理器 opener = urllib.request.build_opener( cookie_handler, proxy_handler, urllib.request.HTTPSHandler() # 默认HTTPS处理器 ) # 第一次请求:服务器设置Cookie resp1 = opener.open('https://example.com/login') # 第二次请求:自动携带前面的Cookie resp2 = opener.open('https://example.com/dashboard') # 查看当前Cookie for cookie in cookie_jar: print(f'{cookie.name}: {cookie.value}')

核心要点:urllib的认证体系基于OpenerDirector和Handler模式。HTTPBasicAuthHandler实现基本认证,ProxyHandler配置网络代理,HTTPCookieProcessor管理Cookie。build_opener()将多个处理器组合为自定义客户端。install_opener()可设为全局默认,简化后续调用。

五、urllib.error

urllib.error模块定义了网络请求过程中可能出现的异常,主要包含URLError和HTTPError两个异常类。合理的异常处理是编写健壮网络程序的基石,了解这些异常的层次结构和适用场景,能够帮助开发者在网络错误发生时做出恰当的响应。

异常层次结构

URLError是OSError的子类,是所有urllib异常的基类。HTTPError继承自URLError,专门处理服务器返回的HTTP错误状态码(如404 Not Found、403 Forbidden、500 Internal Server Error等)。HTTPError对象既是异常又是HTTP响应,这意味着它既可以提供错误信息,也可以读取服务器返回的错误页面内容。

import urllib.request import urllib.error url = 'https://httpbin.org/status/404' # 返回404状态码 try: response = urllib.request.urlopen(url) except urllib.error.HTTPError as e: print(f'HTTP错误状态码: {e.code}') # 404 print(f'错误原因: {e.reason}') # Not Found print(f'响应头: {e.headers}') # HTTPError对象也有read()方法 print(f'错误页面内容: {e.read().decode()[:200]}') except urllib.error.URLError as e: print(f'URL错误: {e.reason}')

URLError — 通用网络错误

URLError通常表示底层网络问题而非服务器业务错误,例如DNS解析失败、连接被拒绝、超时、网络不可达等。抓住URLError异常可以覆盖所有网络层面的错误场景,提供统一的错误处理入口。errno和strerror属性提供了更深层的系统错误信息。

import urllib.request import urllib.error try: # 尝试连接一个不存在的域名 response = urllib.request.urlopen('https://this-domain-does-not-exist-12345.com', timeout=5) except urllib.error.URLError as e: print(f'错误类型: {type(e).__name__}') print(f'错误原因: {e.reason}') # e.reason 可能是一个socket.gaierror或socket.timeout if hasattr(e.reason, 'errno'): print(f'系统错误码: {e.reason.errno}')

最佳异常处理模式

在实际项目中,推荐按HTTPError在前、URLError在后的顺序捕获异常,因为HTTPError是URLError的子类,必须先捕获更具体的异常。同时建议对特定HTTP状态码进行细粒度处理,实现差异化的错误恢复策略。

import urllib.request import urllib.error import time def fetch_with_retry(url, max_retries=3): for attempt in range(max_retries): try: with urllib.request.urlopen(url, timeout=10) as response: return response.read().decode('utf-8') except urllib.error.HTTPError as e: if e.code == 429: # 请求过频繁,等待后重试 wait = int(e.headers.get('Retry-After', 5)) print(f'频率限制,等待 {wait} 秒后重试') time.sleep(wait) elif e.code >= 500: # 服务器错误,重试 print(f'服务器错误 {e.code},重试第 {attempt+1} 次') time.sleep(2 ** attempt) # 指数退避 else: raise # 其他HTTP错误直接抛出 except urllib.error.URLError as e: print(f'网络错误: {e.reason},重试第 {attempt+1} 次') time.sleep(3) raise Exception(f'所有重试均失败: {url}')

核心要点:HTTPError处理服务端业务错误(4xx/5xx状态码),URLError处理底层网络故障。异常捕获顺序须先HTTPError再URLError。结合重试机制、指数退避和状态码判断,可以构建健壮的网络请求流程。HTTPError对象的read()方法可读取服务器返回的错误详情。

六、urllib.robotparser

urllib.robotparser模块提供了对robots.txt文件(爬虫排除标准)的解析支持。robots.txt是网站根目录下的一个文本文件,用于告知网络爬虫哪些路径可以访问、哪些路径禁止访问。对于编写合规的网络爬虫而言,遵守robots.txt协议是基本的网络礼仪和法律要求。

RobotFileParser — 爬虫协议解析器

RobotFileParser是robotparser模块的核心类,负责加载和解析robots.txt文件,并提供查询接口判断特定URL是否允许爬取。该类按行读取robots.txt的规则,构建内部规则表,然后通过can_fetch()方法响应爬虫的访问许可查询。

import urllib.robotparser # 创建RobotFileParser实例 rp = urllib.robotparser.RobotFileParser() # 方式一:直接设置URL,让parse()去读取 rp.set_url('https://www.example.com/robots.txt') rp.read() # 查询特定User-Agent是否可以访问某路径 can_fetch_home = rp.can_fetch('MyBot/1.0', 'https://www.example.com/') can_fetch_admin = rp.can_fetch('MyBot/1.0', 'https://www.example.com/admin/') print(f'允许爬取首页: {can_fetch_home}') # True(通常情况) print('允许爬取管理页: {can_fetch_admin}') # False(通常情况)

核心方法详解

RobotFileParser提供了以下核心方法:set_url()设置robots.txt的URL地址;read()从该URL读取并解析robots.txt内容;parse()直接解析字符串或文件行内容;can_fetch(useragent, url)查询给定爬虫是否允许访问指定URL;mtime()和modified()用于获取和设置文件最后修改时间,配合缓存机制减少重复请求;site_maps()提取robots.txt中声明的SiteMap索引。

import urllib.robotparser rp = urllib.robotparser.RobotFileParser() # 直接从字符串内容解析(适用于本地缓存) robots_content = """\ User-agent: * Disallow: /private/ Disallow: /tmp/ Allow: /public/ User-agent: Googlebot Disallow: /admin/ Sitemap: https://example.com/sitemap.xml """ rp.parse(robots_content.splitlines()) # 查询不同的User-Agent print(rp.can_fetch('*', 'https://example.com/public/')) # True print(rp.can_fetch('*', 'https://example.com/private/')) # False print(rp.can_fetch('Googlebot', 'https://example.com/admin/')) # False print(rp.can_fetch('Bingbot', 'https://example.com/admin/')) # True(*允许) # 获取SiteMaps print(rp.site_maps()) # ['https://example.com/sitemap.xml'] # 检查文件修改时间(用于缓存控制) print(f'最后修改时间: {rp.mtime()}')

核心要点:robotparser是编写合规网络爬虫的基础工具。can_fetch()是核心查询方法,传入User-Agent字符串和目标URL即可获得爬取许可判断。parse()支持从字符串内容直接解析,适合本地缓存场景。site_maps()可提取Sitemap索引。建议在网络爬虫项目中始终先查询robots.txt再发起实际请求。

七、实战案例与总结

通过前六个章节的学习,我们已经掌握了urllib四大子模块的核心功能。本章通过三个典型实战案例展示urllib在实际开发中的综合应用,并给出模块整体总结和学习路线建议。

案例一:网页抓取与内容提取

使用urllib.request结合自定义请求头抓取网页内容,模拟浏览器访问行为以绕过简单的反爬虫检查。配合正则表达式或HTML解析库,可以提取网页中的特定信息。

import urllib.request import urllib.parse import re def fetch_webpage(url): # 模拟主流浏览器请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Accept-Encoding': 'gzip, deflate', } req = urllib.request.Request(url, headers=headers) try: with urllib.request.urlopen(req, timeout=15) as response: # 处理可能的gzip压缩 content_encoding = response.headers.get('Content-Encoding') html = response.read() if content_encoding == 'gzip': import gzip html = gzip.decompress(html) return html.decode('utf-8', errors='replace') except urllib.error.HTTPError as e: print(f'HTTP错误: {e.code}') except urllib.error.URLError as e: print(f'网络错误: {e.reason}') return None # 使用示例 html = fetch_webpage('https://httpbin.org/html') if html: # 提取页面标题 title_match = re.search(r'(.*?)', html, re.IGNORECASE) if title_match: print(f'页面标题: {title_match.group(1)}')

案例二:RESTful API调用

使用urllib发送JSON格式的POST请求调用RESTful API,展示如何处理JSON数据的序列化与反序列化,以及如何正确设置Content-Type请求头。

import urllib.request import urllib.parse import json def call_api(endpoint, method='GET', params=None, data=None, token=None): # 构建完整URL if params: endpoint += '?' + urllib.parse.urlencode(params) # 设置请求头 headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', } if token: headers['Authorization'] = f'Bearer {token}' # 序列化JSON数据 body = None if data is not None: body = json.dumps(data).encode('utf-8') req = urllib.request.Request(endpoint, data=body, headers=headers, method=method) try: with urllib.request.urlopen(req, timeout=30) as response: resp_data = json.loads(response.read().decode('utf-8')) return resp_data except urllib.error.HTTPError as e: print(f'API错误 [{e.code}]: {e.read().decode()}') except json.JSONDecodeError: print('响应不是有效的JSON格式') return None # 使用示例:GitHub API result = call_api( endpoint='https://api.github.com/search/repositories', params={'q': 'language:python', 'sort': 'stars', 'per_page': 5} ) if result: for repo in result['items']: print(f"{repo['name']}: {repo['stargazers_count']} stars")

案例三:文件下载与进度显示

使用urllib实现大文件的分块下载,在命令行显示下载进度。关键技巧在于以二进制模式('wb')写入文件,使用分块读取避免内存溢出,通过Content-Length头计算总大小并显示下载百分比。

import urllib.request import urllib.error import os def download_file(url, save_path): # 先发送HEAD请求获取文件大小 req = urllib.request.Request(url, method='HEAD') with urllib.request.urlopen(req) as resp: total_size = int(resp.headers.get('Content-Length', 0)) print(f'文件大小: {total_size / 1024 / 1024:.2f} MB') # 分块下载 downloaded = 0 chunk_size = 8192 req = urllib.request.Request(url, headers={ 'User-Agent': 'Downloader/1.0' }) with urllib.request.urlopen(req) as response: with open(save_path, 'wb') as f: while True: chunk = response.read(chunk_size) if not chunk: break f.write(chunk) downloaded += len(chunk) # 显示进度 if total_size > 0: percent = downloaded * 100 / total_size print(f'\r下载进度: {percent:.1f}% ({downloaded/1024/1024:.2f}MB)', end='') print('\n下载完成!') # 使用示例 # download_file('https://example.com/large-file.zip', './download/large-file.zip')

模块总结

urllib是Python标准库中功能完备的URL处理工具集合,掌握它可以完成大部分日常网络编程任务。下表总结了七个章节的核心知识点:

章节核心概念重点函数/类常见用途
概述四个子模块分工request/parse/error/robotparser模块选择
urllib.requestURL请求发送urlopen(), Request, build_opener网页抓取、POST请求
urllib.parseURL解析与编码urlparse, urlencode, quote, unquote参数构建、URL处理
认证与Cookie高级HTTP功能HTTPBasicAuthHandler, ProxyHandler, HTTPCookieProcessor登录、代理、会话维持
urllib.error异常处理体系URLError, HTTPError错误捕获与重试
urllib.robotparser爬虫协议RobotFileParser, can_fetch爬虫合规检查
实战案例综合应用网页抓取、API调用、文件下载项目实战

学习路线建议

对于初学者,建议从urllib.request.urlopen()开始,掌握最基本的GET请求和响应读取。然后学习urllib.parse的URL解析和参数编码,这是日常开发中使用频率最高的子模块。接着深入了解Request类和OpenerDirector机制,掌握自定义请求头、Cookie和代理配置。urllib.error和urllib.robotparser可以作为进阶内容在有实际需求时学习。

提示:虽然Requests库在易用性上优于urllib,但理解urllib的底层原理对于掌握HTTP协议、调试网络请求以及在不便安装第三方库的环境中开发仍然非常重要。建议先学好urllib,再过渡到Requests库。

掌握了urllib之后,可以进一步学习相关的Python网络编程库,包括http.server(简易HTTP服务器)、socketserver(网络服务框架)、ssl(SSL/TLS加密通信)、selectors(I/O多路复用)以及第三方库Requests、aiohttp(异步HTTP)等,逐步构建完整的网络编程知识体系。