3. Python 请求库入门:安装 requests 库、发送第一个 GET 请求、处理响应对象
说实话,做后端开发这么多年,我打交道最多的第三方库就是 requests。它几乎成了 Python 世界里调用 HTTP 接口的「标配」。你想想看,不管是调个天气 API,还是对接微信支付,底层都是发 HTTP 请求。今天我们就从零开始,把 requests 装好、跑通、用熟。
3.1 安装 requests 库
安装这事,其实一句话就能说清楚。但我还是想啰嗦两句——千万别在系统全局装。我早期吃过这个亏,装了一堆库,最后项目之间版本冲突,搞得焦头烂额。
正确的做法是:先建一个虚拟环境,再装库。
# 创建虚拟环境(Python 3.3+ 自带 venv)
python -m venv myenv
# 激活虚拟环境(Windows)
myenv\Scripts\activate
# 激活虚拟环境(Mac / Linux)
source myenv/bin/activate
# 安装 requests
pip install requests
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
装完之后,验证一下:
python -c "import requests; print(requests.__version__)"
能看到版本号,就说明装好了。嗯,就是这么简单。
3.2 发送第一个 GET 请求
好,库装好了,我们来发第一个请求。我个人习惯先拿一个公开的 API 练手,比如 httpbin.org,它专门用来测试 HTTP 请求。
import requests
url = "https://httpbin.org/get"
response = requests.get(url)
print(response.text)
跑一下,你会看到一堆 JSON 格式的返回内容。里面包含了你的请求头、IP 地址等信息。说白了,requests.get() 就是帮我们封装了底层的 socket 连接、DNS 解析、SSL 握手这些脏活累活。
requests.get(url) 返回的是一个 Response 对象,不是纯文本。后续所有操作都基于这个对象。
3.3 处理响应对象
拿到 Response 对象之后,我们能做的事情就多了。我把它拆成三个最常用的属性来讲:text、json()、status_code。
3.3.1 response.text —— 原始文本
.text 返回的是字符串格式的响应体。适合用来处理 HTML、XML 或者纯文本接口。
response = requests.get("https://httpbin.org/get")
print(type(response.text)) # <class 'str'>
print(response.text[:200]) # 只打印前 200 个字符
我曾经对接过一个老系统的接口,返回的是 XML 格式。当时直接用 .text 拿到字符串,然后用 xml.etree.ElementTree 解析,非常顺畅。
3.3.2 response.json() —— 解析 JSON
现在大部分 RESTful API 都返回 JSON。.json() 方法直接帮你把 JSON 字符串转成 Python 字典或列表。省去了 json.loads() 这一步。
response = requests.get("https://httpbin.org/get")
data = response.json()
print(data["origin"]) # 你的 IP 地址
print(data["headers"]) # 请求头信息
.json() 会抛出 json.JSONDecodeError。所以,我建议先检查 status_code,再决定是否解析。
3.3.3 response.status_code —— 状态码
状态码是 HTTP 响应的「脸色」。200 表示一切正常,404 表示资源不存在,500 表示服务器挂了。我每次写请求代码,第一件事就是判断状态码。
response = requests.get("https://httpbin.org/status/404")
if response.status_code == 200:
print("请求成功")
elif response.status_code == 404:
print("资源不存在")
else:
print(f"出错了,状态码:{response.status_code}")
其实 requests 还提供了一个更优雅的方式——response.raise_for_status()。它会自动检查状态码,如果 >= 400 就抛出异常。
response = requests.get("https://httpbin.org/status/500")
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
print(f"HTTP 错误:{e}")
我个人更推荐用 raise_for_status(),代码更干净,而且异常处理也更统一。
3.4 本章知识体系
下面这张图,帮你把今天的内容串起来:
3.5 避坑指南
- 我曾经在没检查状态码的情况下直接调
.json(),结果 API 返回了 502 错误页面,程序直接崩溃。从那以后,我养成了先判断status_code的习惯。 - 注意:
requests.get()默认不会设置超时。如果 API 挂了,你的程序会一直卡住。建议加上timeout参数:requests.get(url, timeout=5)。 - 还有一点:
.text和.content的区别。.text是解码后的字符串,.content是原始的字节数据。处理图片、文件时用.content。
3.6 完整示例
最后,给你一个完整的实战片段。假设我们要查一个城市的天气(用公开的 wttr.in 服务):
import requests
city = "Beijing"
url = f"https://wttr.in/{city}?format=%C+%t"
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
# 返回的是纯文本,比如 "Sunny +25°C"
weather_info = response.text.strip()
print(f"{city} 的天气:{weather_info}")
except requests.exceptions.RequestException as e:
print(f"请求失败:{e}")
你看,整个流程就是:发请求 → 检查状态 → 解析内容。后面我们讲 POST 请求、Session、Cookie 的时候,都是在这个基础上加东西。