### 一、它是什么一个HTTP请求库但不止是请求库。requests在Python生态里就像一把瑞士军刀——当你需要和网络服务器打交道时第一反应就是找它。它把最底层的socket通信、SSL握手、重定向处理这些脏活全包了留给你的就是一些直观的方法get就是获取post就是提交。举个生活中的例子你点外卖时外卖员要走到商家门口建立连接说“我要取餐”发送请求然后拿到餐响应内容。requests就是那个什么都能替你跑腿的外卖员但你不用知道外卖员是怎么骑车的。二、它能做什么最基础的发邮件。但实际场景里我主要用它做这几件事抓取网页内容写爬虫时它负责拿到HTML。比如抓一个新闻网站的标题一行requests.get(url)就能拿到源码比urllib的坑少太多。调用API接口现在几乎所有服务都提供RESTful API。传参、处理JSON、带token认证它都支持得挺好。文件上传/下载大的分片下载可能要用别的库但小文件、小图片它直接写文件流就够用。监控与测试写个小脚本定时检查某个服务是否正常返回200它再合适不过。印象很深的一次帮一个同事调试一个内部系统。对方要求登录后带cookie请求资源用requests.Session自动管理cookie前后改了三个参数半小时搞定。要是用原始socket写得加一个星期的班。三、怎么使用装它很简单pip install requests。但实际用起来有几个细节值得提importrequests# 最基础的GETresponserequests.get(https://api.github.com)print(response.status_code)# 200# 带参数的GET - 自动拼接到URL后面payload{key1:value1,key2:value2}responserequests.get(https://httpbin.org/get,paramspayload)# POST提交表单form_data{username:hello,password:world}responserequests.post(https://httpbin.org/post,dataform_data)# POST提交JSON - 现在开发中更常用json_data{username:hello,password:world}responserequests.post(https://httpbin.org/post,jsonjson_data)一个容易忽略的地方响应内容编码。很多时候直接response.text会乱码其实可以先检查response.encoding再手动设置为实际编码responserequests.get(url)response.encodingresponse.apparent_encoding# 自动探测编码textresponse.text# 现在不会乱码了还有就是超时设置。不加超时的代码会挂在那里等你半小时responserequests.get(url,timeout5)# 连接读取一共5秒# 更细粒度控制responserequests.get(url,timeout(3,5))# 连接3秒读取5秒四、最佳实践干了几年的开发踩过不少坑总结几条1. 用Session复用连接很多新手每个请求都新建连接效率低得像每次进饭店都重新装修厨房。用Session可以复用TCP连接而且自动管理cookiesessionrequests.Session()session.headers.update({User-Agent:my-app})# 登录session.post(https://example.com/login,data{user:admin,pass:123})# 后续请求自动带cookiesession.get(https://example.com/profile)2. 异常处理要细致requests的异常继承关系很清晰但很多人只catch一个Exception。我习惯这样try:responserequests.get(url,timeout5)response.raise_for_status()# 非200状态码会抛HTTPErrorexceptrequests.ConnectionError:print(连不上网络)exceptrequests.Timeout:print(服务器超时)exceptrequests.HTTPError:print(fHTTP错误:{response.status_code})3. 重试机制不可少网络不可靠特别是调第三方接口时。可以用urllib3的Retry配合Sessionfromrequests.adaptersimportHTTPAdapterfromurllib3.util.retryimportRetry sessionrequests.Session()retriesRetry(total3,backoff_factor0.1,status_forcelist[500,502,503,504])adapterHTTPAdapter(max_retriesretries)session.mount(http://,adapter)session.mount(https://,adapter)这样当遇到服务器临时错误时会自动重试3次而且每次间隔逐渐加长backoff。五、和同类技术对比说到同类库绕不开Python自带的那个urllib。以前用urllib.request写代码光构造一个带参数的GET请求就得写好几行fromurllib.parseimporturlencodefromurllib.requestimporturlopen,Request paramsurlencode({key:value})requestRequest(fhttp://example.com?{params},headers{User-Agent:...})responseurlopen(request).read()用requests只需要一行。所以现在很少看到有人直接裸写urllib了。另外一个是httpx算是后起之秀。它最突出的特点是支持异步——如果你用asyncio写并发httpx是天然的选择。但同步场景下requests的生态更成熟各种中间件、插件、文档都比httpx完善。比如处理OAuth2认证requests-oauthlib直接就能用。还有个比较冷门但用的人也不少的是aiohttp。它主打异步功能全面但API设计得比较“重”学习成本比httpx高。一般做高并发爬虫时才会选它。最后提一句urllib3它是requests的底层库功能更强但API更原始。99%的场景你不需要直接用它除非你要做一些很底层的控制比如自定义连接池大小、使用纯HTTP1.1协议等。说实话在实际项目中我99%的HTTP请求都是用requests完成的。它就像家里的平底锅——什么菜都能炒不惊艳但足够可靠。只有当明确需要异步、或者要控制超低级别的网络参数时我才会考虑换别的工具。