第 2 章 · GET 请求与响应处理
本章目标:掌握 GET 请求的完整用法,理解响应对象的所有核心属性,学会从 API 返回中提取所需数据。
2.1 GET 请求基础
GET 是最常用的 HTTP 方法,用于从服务器获取资源。requests 和 httpx 的 GET API 几乎一致:
python
import requests
# 最简单的 GET 请求
response = requests.get('https://httpbin.org/get')
# 使用 httpx 实现相同功能
import httpx
response = httpx.get('https://httpbin.org/get')GET 请求可以携带 URL 参数(查询字符串),用于过滤或分页:
python
import requests
# 方法一:直接在 URL 中拼接(不推荐,容易出错)
resp = requests.get('https://api.github.com/search/repositories?q=python&sort=stars')
# 方法二:使用 params 参数(推荐)
params = {'q': 'python', 'sort': 'stars'}
resp = requests.get('https://api.github.com/search/repositories', params=params)
# 查看实际请求的 URL
print(resp.url)
# 输出: https://api.github.com/search/repositories?q=python&sort=starsparams 参数接受字典,requests 会自动编码为 URL 查询字符串。值为 None 的键会被跳过。
2.2 响应对象核心属性
每次请求都返回一个响应对象(requests.Response 或 httpx.Response),包含丰富的信息:
python
import requests
resp = requests.get('https://httpbin.org/get')
# 状态码:HTTP 响应状态
print(resp.status_code) # 200
# 文本内容:自动解码的字符串
print(resp.text[:200])
# 二进制内容:原始字节(适用于图片、文件等)
content = resp.content
# 响应的 URL(可能被重定向)
print(resp.url)
# 请求头
print(resp.headers['Content-Type'])
# 原始响应头(支持大小写不敏感访问)
print(resp.headers.get('content-type'))响应编码自动检测:requests 会根据 HTTP 头部的 Content-Type 和 charset 自动猜测编码:
python
resp = requests.get('https://example.com/page')
# 查看自动检测的编码
print(resp.encoding) # 如 'utf-8'
# 手动设置编码(如果自动检测错误)
resp.encoding = 'gbk'
print(resp.text)2.3 JSON 响应处理
现代 API 绝大多数返回 JSON 格式数据。requests 提供便捷的 .json() 方法:
python
import requests
# GitHub API 返回 JSON
resp = requests.get('https://api.github.com/user')
# 解析为 Python 字典
data = resp.json()
print(data['login'])
print(data['public_repos'])
# 处理嵌套结构
for repo in data.get('repos', [])[:3]:
print(f"- {repo['name']}: {repo['description']}")
# 检查 Content-Type(可选的安全习惯)
if resp.headers.get('Content-Type') == 'application/json':
data = resp.json()注意:如果响应不是有效 JSON,.json() 会抛出 requests.exceptions.JSONDecodeError。生产代码应该加异常处理:
python
try:
data = resp.json()
except requests.exceptions.JSONDecodeError:
print('响应不是 JSON 格式,使用 text 属性')
print(resp.text)2.4 复杂查询与 URL 模板
当需要构建复杂的查询时,可以组合多个参数:
python
import requests
# GitHub API 分页查询
page = 1
per_page = 10
params = {
'q': 'machine+learning',
'sort': 'stars',
'order': 'desc',
'page': page,
'per_page': per_page
}
resp = requests.get('https://api.github.com/search/repositories', params=params)
data = resp.json()
# GitHub API 返回分页信息
print(f"Total: {data['total_count']}")
for item in data['items']:
print(f"- {item['full_name']}: {item['stargazers_count']} stars")对于 RESTful API,经常需要动态构建 URL:
python
import requests
# 使用 f-string 构建 URL(注意编码)
username = 'octocat'
resp = requests.get(f'https://api.github.com/users/{username}')
# 或者使用 requests 提供的 URL 构建工具
from urllib.parse import urljoin
base_url = 'https://api.github.com'
user_url = urljoin(base_url, f'users/{username}')
resp = requests.get(user_url)2.5 本章小结
- GET 请求通过
requests.get(url)发起,httpx 语法相同; - 响应对象包含
status_code、text、content、headers等核心属性; - JSON 响应用
.json()方法解析,注意处理解码异常; params参数自动编码为查询字符串,None值的键会被跳过。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. requests.get() 的 params 参数主要作用是什么?
2. 响应对象 resp.text 和 resp.content 的区别是?
3. 调用 resp.json() 时发生 JSONDecodeError,可能的原因是?
4. 以下哪个属性可以查看实际发出的请求 URL(含查询字符串)?
🛠️ 动手实践
- 用 requests 获取
https://httpbin.org/get的响应,打印状态码和所有响应头。 - 访问 GitHub API(
https://api.github.com)获取用户信息,解析并打印用户名和公开仓库数。 - 使用 params 参数查询
https://httpbin.org/get?name=test&age=25,验证 URL 是否正确编码。