网络通信的基石:Python HTTP请求库完全解析

发布时间:2026/5/20 6:39:55

网络通信的基石:Python HTTP请求库完全解析 大家好我是ZTLJQ希望你看完之后能对你有所帮助不足请指正共同学习交流个人主页ZTLJQ的主页欢迎各位→点赞 收藏⭐️ 留言​系列果你对这个系列感兴趣的话专栏 - ​​​​​​Python从零到企业级应用短时间成为市场抢手的程序员✔说明⇢本人讲解主要包括Python爬虫、JS逆向、Python的企业级应用如果你对这个系列感兴趣的话可以关注订阅哟为什么需要专门的HTTP库Python内置的urllib模块功能强大但其API相对底层且繁琐。想象一下为了发送一个带自定义头部和超时设置的POST请求你需要写上十几行代码...幸运的是社区诞生了像requests这样被誉为“人类为人类创造的HTTP库”。它以简洁、优雅的API彻底改变了Python的网络编程格局。本篇博客将带你从基础到高级全面掌握requests和它的现代化继任者httpx并对比它们与urllib的差异。第一部分requests- 无可争议的王者requests(pip install requests) 因其极简的API和强大的功能成为了事实上的标准。1.1 基础请求方法import requests # ---- GET 请求获取数据 ---- response requests.get(https://httpbin.org/get) # 检查响应状态 if response.status_code 200: print(请求成功!) else: print(f请求失败状态码: {response.status_code}) # 获取响应内容 print(response.text) # 字符串形式 # print(response.content) # 字节形式 (bytes)对于图片等二进制数据有用 # 将JSON响应直接解析为Python字典 json_data response.json() print(json_data[url]) # https://httpbin.org/get # ---- POST 请求发送数据 ---- # 发送表单数据 (application/x-www-form-urlencoded) form_data {key1: value1, key2: value2} post_response requests.post(https://httpbin.org/post, dataform_data) # 发送JSON数据 (application/json) json_payload {name: Alice, age: 30} post_json_response requests.post(https://httpbin.org/post, jsonjson_payload) # ---- PUT / DELETE 请求 ---- put_response requests.put(https://httpbin.org/put, json{data: updated}) delete_response requests.delete(https://httpbin.org/delete)解析:requests的核心在于每个HTTP方法get,post,put,delete都对应一个同名函数参数直观。1.2 关键参数详解import requests # ---- 1. 参数 (params) ---- # 将参数自动附加到URL的查询字符串中 params {page: 2, size: 10, q: python tutorial} response requests.get(https://api.example.com/search, paramsparams) # 等价于访问: https://api.example.com/search?page2size10qpythontutorial # ---- 2. 自定义头部 (headers) ---- headers { User-Agent: MyApp/1.0, Authorization: Bearer your-jwt-token-here, # Bearer Token 认证 Content-Type: application/json # 通常由 requests 自动设置 } response requests.get(https://api.example.com/data, headersheaders) # ---- 3. 超时 (timeout) ---- # 非常重要防止程序无限期等待 try: response requests.get(https://slow-website.com, timeout5) # 5秒后超时 except requests.exceptions.Timeout: print(请求超时!) except requests.exceptions.RequestException as e: print(f请求出错: {e}) # ---- 4. 处理重定向 (allow_redirects) ---- # 默认 allow_redirectsTrue会自动跟随重定向 # 如果想禁用设为 False response requests.get(http://github.com, allow_redirectsFalse) print(response.status_code) # 301 print(response.headers[Location]) # https://github.com # ---- 5. 会话 (Session) ---- # Session 对象可以跨请求保持 cookies 和 headers非常高效。 session requests.Session() session.headers.update({User-Agent: MyApp/1.0}) # 登录 (假设这个请求会返回一个 session cookie) login_data {username: user, password: pass} session.post(https://example.com/login, datalogin_data) # 后续请求会自动携带登录获得的 cookie profile_response session.get(https://example.com/profile) dashboard_response session.get(https://example.com/dashboard) # 最后关闭会话 session.close() # 或使用 with 语句1.3 实际案例构建一个简单的REST客户端import requests from typing import Optional, Dict, Any class APIClient: def __init__(self, base_url: str, api_key: str): self.base_url base_url.rstrip(/) # 移除末尾斜杠 self.session requests.Session() self.session.headers.update({ Authorization: fBearer {api_key}, Content-Type: application/json }) def get(self, endpoint: str, params: Optional[Dict] None) - Dict[Any, Any]: 封装GET请求 url f{self.base_url}/{endpoint.lstrip(/)} try: response self.session.get(url, paramsparams, timeout10) response.raise_for_status() # 如果不是2xx状态码抛出HTTPError return response.json() except requests.exceptions.HTTPError as e: print(fHTTP错误: {e}) if e.response.status_code 404: print(资源未找到) elif e.response.status_code 401: print(认证失败) except requests.exceptions.RequestException as e: print(f请求异常: {e}) return {} def post(self, endpoint: str, data: Dict) - Dict[Any, Any]: 封装POST请求 url f{self.base_url}/{endpoint.lstrip(/)} try: response self.session.post(url, jsondata, timeout10) response.raise_for_status() return response.json() # 假设服务器返回创建的资源 except Exception as e: print(fPOST请求失败: {e}) return {} def close(self): 关闭会话 self.session.close() # 使用客户端 client APIClient(https://jsonplaceholder.typicode.com, dummy-key) # 获取用户列表 users client.get(/users) for user in users[:2]: # 打印前两个 print(user[name]) # 创建一个新帖子 new_post client.post(/posts, { title: My New Post, body: This is the content., userId: 1 }) print(创建的帖子:, new_post) # 别忘了关闭 client.close()解析: 这个案例展示了如何利用Session和良好的错误处理来构建一个健壮、可复用的API客户端。第二部分httpx- 现代化的全能选手httpx(pip install httpx) 是一个现代化的HTTP客户端旨在成为requests的替代品同时增加了许多激动人心的新特性。2.1 同步与异步支持这是httpx最大的亮点。你可以用几乎相同的API编写同步和异步代码。import httpx import asyncio # ---- 同步模式 (类似 requests) ---- def sync_example(): response httpx.get(https://httpbin.org/get) print(response.status_code) print(response.json()[url]) sync_example() # ---- 异步模式 (async/await) ---- async def async_example(): async with httpx.AsyncClient() as client: response await client.get(https://httpbin.org/get) print(response.status_code) print(response.json()[url]) # 运行异步函数 asyncio.run(async_example())优势: 异步I/O可以在等待网络响应时释放控制权执行其他任务极大地提高了I/O密集型应用如爬虫、API聚合器的并发性能。2.2 HTTP/2 支持httpx原生支持HTTP/2协议可以更高效地复用连接减少延迟。import httpx # 默认情况下如果服务器支持httpx 会协商使用 HTTP/2 with httpx.Client(http2True) as client: response client.get(https://http2.golang.org) print(fHTTP Version: {response.http_version}) # HTTP/22.3 实际案例高效的异步爬虫​ 1import httpx 2import asyncio 3from bs4 import BeautifulSoup 4 5# 我们要抓取的多个URL 6urls [ 7 https://httpbin.org/delay/1, 8 https://httpbin.org/delay/2, 9 https://httpbin.org/delay/1, 10] 11 12async def fetch_title(client: httpx.AsyncClient, url: str) - str: 13 异步获取单个页面的标题 14 try: 15 response await client.get(url, timeout10) 16 response.raise_for_status() 17 18 # 使用 BeautifulSoup 解析HTML 19 soup BeautifulSoup(response.text, html.parser) 20 title_tag soup.find(title) 21 title title_tag.get_text(stripTrue) if title_tag else No Title 22 23 return f{url}: {title} 24 except Exception as e: 25 return f{url}: Error - {e} 26 27async def main(): 28 # 创建一个共享的异步客户端 29 async with httpx.AsyncClient() as client: 30 # 使用 asyncio.gather 并发执行所有请求 31 tasks [fetch_title(client, url) for url in urls] 32 results await asyncio.gather(*tasks) 33 34 for result in results: 35 print(result) 36 37# 运行主协程 38asyncio.run(main()) ​解析: 在同步版本中抓取这三个URL至少需要1214秒。而在异步版本中由于是并发请求总时间大约只有2秒多一点性能提升显著。第三部分与urllib的对比了解urllib有助于理解底层原理。# 使用 urllib 发送一个带参数和头部的GET请求 from urllib import request, parse base_url https://httpbin.org/get params {key: value} query_string parse.urlencode(params) full_url f{base_url}?{query_string} req request.Request( full_url, headers{ User-Agent: MyApp/1.0 } ) try: with request.urlopen(req, timeout5) as response: data response.read().decode(utf-8) # 必须手动解码 print(data) except Exception as e: print(fError: {e})对比:代码量:urllib需要更多样板代码。易用性:requests/httpx的API远胜一筹。功能:requests/httpx内置了JSON处理、会话管理、文件上传等高级功能。学习成本:requests几乎是零成本入门。第四部分最佳实践与陷阱始终设置timeout: 这是最重要的实践防止程序挂起。善用Session/Client: 对于多次请求复用连接能显著提升性能。检查状态码: 不要只依赖try-except主动检查status_code或使用raise_for_status()。处理异常: 捕获RequestException及其子类ConnectionError,Timeout,HTTPError。管理连接: 使用with语句确保Session或Client被正确关闭。考虑异步: 当需要高并发时如爬取大量页面httpx的异步模式是更好的选择。安全: 不要在代码中硬编码敏感信息如API密钥。使用环境变量或配置文件。结语requests重新定义了Python的HTTP体验而httpx则在此基础上引领我们走向异步和HTTP/2的未来。通过本篇博客的学习你应该已经掌握了如何使用requests进行各种HTTP操作并构建健壮的客户端。httpx的强大功能特别是其异步和HTTP/2支持。如何根据项目需求选择合适的库。至关重要的性能和安全最佳实践。

相关新闻