安装 requests 库
你需要确保已经安装了 requests 库,如果尚未安装,可以通过 pip 进行安装:

pip install requests
核心概念:请求与响应
使用 requests 的核心流程是:
- 构造一个请求:指定请求方法(如 GET, POST)、URL、请求头、请求体等。
- 发送请求:使用
requests提供的函数(如requests.get())将请求发送到服务器。 - 接收响应:服务器会返回一个
Response对象,其中包含了服务器的一切响应信息。
让我们从最简单的 GET 请求开始。
发送 GET 请求
GET 请求通常用于从服务器获取数据。
1 最简单的 GET 请求
import requests
# 发送一个 GET 请求到 GitHub 的公共 API
response = requests.get('https://api.github.com')
# 检查请求是否成功 (状态码为 200)
response.raise_for_status() # 如果请求失败 (状态码不是 2xx),则会抛出异常
print(f"状态码: {response.status_code}")
print(f"响应头: {response.headers}")
2 获取响应内容
Response 对象提供了多种方式来访问响应体:

response.text: 以字符串形式返回响应内容。requests会根据Content-Type和HTTP头部自动解码。response.content: 以字节形式返回响应内容,适合处理非文本数据,如图片、文件等。response.json(): 将响应内容解析为 JSON 格式,如果响应不是有效的 JSON,它会抛出JSONDecodeError异常,这是处理 API 响应最常用的方法。
import requests
import json
response = requests.get('https://api.github.com/events')
# 方法一:使用 .json() 解析 (推荐用于 API)
data = response.json()
print("使用 .json() 解析后的第一个事件:")
print(json.dumps(data[0], indent=2, ensure_ascii=False)) # 使用 json 美化输出
# 方法二:使用 .text 获取原始文本
# text_data = response.text
# print("\n使用 .text 获取的原始文本:")
# print(text_data[:200]) # 只打印前200个字符
# 方法三:使用 .content 获取字节流 (下载图片)
# img_response = requests.get('https://www.python.org/static/community_logos/python-logo-master-v3-TM.png')
# with open('python_logo.png', 'wb') as f:
# f.write(img_response.content)
发送 POST 请求
POST 请求通常用于向服务器提交数据,例如提交表单、上传文件或创建新的资源。
1 提交表单数据
当你向网站提交登录表单或搜索表单时,通常就是这种方式,数据被编码为 application/x-www-form-urlencoded 格式。
import requests
# 目标 URL
url = 'https://httpbin.org/post'
# 要提交的表单数据
payload = {
'username': 'testuser',
'password': 'securepassword123'
}
# 发送 POST 请求
response = requests.post(url, data=payload)
# 检查并打印结果
response.raise_for_status()
print(f"状态码: {response.status_code}")
print("服务器收到的表单数据:")
print(response.json()['form']) # httpbin.org 会返回你发送的数据
2 提交 JSON 数据
很多现代 API 要求你发送 JSON 格式的数据,这时你需要设置 Content-Type 请求头。
import requests
import json
url = 'https://httpbin.org/post'
# 要发送的 JSON 数据
json_data = {
'name': 'John Doe',
'age': 30,
'is_student': False
}
# 发送 POST 请求,并指定 JSON 数据
# requests 会自动设置 Content-Type 为 application/json
response = requests.post(url, json=json_data)
# 检查并打印结果
response.raise_for_status()
print(f"状态码: {response.status_code}")
print("服务器收到的 JSON 数据:")
print(response.json()['json']) # httpbin.org 会返回你发送的 JSON
传递 URL 参数
GET 请求常常需要通过 URL 传递参数(?key1=value1&key2=value2)。requests 提供了 params 参数来优雅地处理这个问题。

import requests
# API 端点,用于搜索 GitHub 上的仓库
url = 'https://api.github.com/search/repositories'
# 搜索参数
params = {
'q': 'requests language:python', # 查询关键词
'sort': 'stars', # 按星标数排序
'order': 'desc' # 降序
}
# 发送带有参数的 GET 请求
response = requests.get(url, params=params)
# 检查并打印结果
response.raise_for_status()
search_results = response.json()
print(f"找到 {search_results['total_count']} 个相关仓库")
print("最受欢迎的仓库:")
for repo in search_results['items'][:3]:
print(f"- {repo['name']} (Stars: {repo['stargazers_count']})")
自定义请求头
有些网站或 API 需要特定的请求头才能正常工作,例如设置 User-Agent 来模拟浏览器访问。
import requests
url = 'https://httpbin.org/headers'
# 自定义请求头
headers = {
'User-Agent': 'MyCoolApp/1.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
'Accept-Language': 'en-US,en;q=0.9'
}
response = requests.get(url, headers=headers)
print("服务器接收到的请求头:")
print(response.json()['headers'])
处理响应状态码
检查状态码是判断请求是否成功的关键。
import requests
url = 'https://httpbin.org/status/404'
try:
response = requests.get(url)
# 如果状态码表示失败 (4xx or 5xx),则抛出 HTTPError
response.raise_for_status()
print("请求成功!")
print(response.text)
except requests.exceptions.HTTPError as err:
print(f"HTTP 错误: {err}")
except requests.exceptions.ConnectionError as err:
print(f"连接错误: {err}")
except requests.exceptions.Timeout as err:
print(f"请求超时: {err}")
except requests.exceptions.RequestException as err:
print(f"发生未知错误: {err}")
会话对象 (Session Objects)
当你需要向同一个主机发送多个请求时,使用 Session 对象会非常高效。Session 对象会保持某些参数(如 headers)在请求之间,并使用一个底层的 TCP 连接(连接池),从而提升性能。
import requests
# 创建一个 Session 对象
with requests.Session() as session:
# 设置会话级别的默认值
session.headers.update({'User-Agent': 'MyApp/1.0'})
# 第一次请求
response1 = session.get('https://httpbin.org/headers')
print("第一次请求的 User-Agent:")
print(response1.json()['headers']['User-Agent'])
# 第二次请求,会自动使用第一次设置的 User-Agent
response2 = session.get('https://httpbin.org/headers')
print("\n第二次请求的 User-Agent (与第一次相同):")
print(response2.json()['headers']['User-Agent'])
超时设置
为了避免程序因为网络问题而无限期等待,设置超时是非常重要的。
# 设置连接超时和读取超时
# connect: 3秒内无法连接到服务器
# read: 3秒内服务器没有返回任何数据
try:
response = requests.get('https://httpbin.org/delay/5', timeout=(3.05, 27))
print(response.text)
except requests.exceptions.Timeout:
print("请求超时!")
完整示例:爬取知乎热榜
这个综合示例展示了如何结合以上知识点来爬取一个网站的数据。
import requests
import json
import time
def get_zhihu_hotlist():
"""
获取知乎热榜前10条
"""
url = 'https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=10'
# 设置请求头,模拟浏览器访问
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Referer': 'https://www.zhihu.com/hot' # 防止被反爬
}
try:
# 发送 GET 请求
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 检查请求是否成功
# 解析 JSON 数据
data = response.json()
print("知乎热榜 Top 10:")
print("=" * 30)
# 遍历并打印结果
for i, item in enumerate(data['data'], 1):
title = item['target']['title']
excerpt = item['target']['excerpt']
print(f"{i}. {title}")
print(f" {excerpt}")
print("-" * 30)
except requests.exceptions.RequestException as e:
print(f"发生错误: {e}")
# 运行函数
if __name__ == '__main__':
get_zhihu_hotlist()
| 功能 | 方法/属性 | 描述 |
|---|---|---|
| 发送请求 | requests.get(url), requests.post(url) |
发送 HTTP 请求 |
| URL参数 | requests.get(url, params={'key': 'val'}) |
优雅地构建带查询参数的 URL |
| 请求体 | requests.post(url, data=form_data) |
提交表单数据 |
requests.post(url, json=payload) |
提交 JSON 数据 | |
| 请求头 | requests.get(url, headers={'User-Agent': '...'}) |
自定义 HTTP 请求头 |
| 响应状态 | response.status_code |
获取 HTTP 状态码 |
response.raise_for_status() |
如果状态码错误则抛出异常 | |
response.text |
获取解码后的文本内容 | |
response.content |
获取原始字节内容 | |
response.json() |
解析为 JSON 对象 | |
| 会话 | with requests.Session() as s: |
创建一个会话对象,用于保持连接和参数 |
| 超时 | requests.get(url, timeout=5) |
设置请求超时时间 |
| 错误处理 | try...except requests.exceptions... |
捕获网络请求中可能发生的错误 |
掌握这些基本用法,你就可以使用 requests 库高效地处理绝大多数网络数据获取任务了。
