分页与大型数据集采集
处理分页、next_cursor 模式,使用 time.sleep 实现速率限制,并显示进度条
分页与大型数据集采集 是 CoddyKit 上的免费 Learn AI with Python 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn AI with Python 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn AI with Python 课程共包含 4 节课。
为什么需要分页
应用程序编程接口很少会在一次响应中返回数百万条记录。它们会将结果拆分成多个页面,使每次响应都保持小巧且快速。
要收集完整的数据集,您必须遍历每个页面并合并结果。本课将介绍常见的分页方式,以及速率限制和进度跟踪。
按页码分页
最简单的方案使用 page 参数。您可以不断递增它,直到应用程序编程接口返回空页面。
import requests
all_items = []
page = 1
while True:
resp = requests.get(url, params={"page": page, "per_page": 100}, timeout=10)
resp.raise_for_status()
items = resp.json()
if not items:
break
all_items.extend(items)
page += 1
print(len(all_items), "items collected")游标/下一网址分页
许多现代应用程序编程接口会返回指向下一页的下一网址或游标令牌。只要下一链接存在,您就持续循环。
这种方式很健壮,因为下一页从哪里开始由服务器控制。
all_items = []
next_url = "https://api.example.com/items?limit=100"
while next_url:
resp = requests.get(next_url, timeout=10)
resp.raise_for_status()
data = resp.json()
all_items.extend(data["results"])
next_url = data.get("next") # None when no more pages
print(len(all_items))使用 time.sleep 遵守速率限制
应用程序编程接口会限制您每秒或每分钟可以发送的请求数量。频繁请求会返回 429 Too Many Requests,或者导致您被阻止访问。
请在请求之间插入短暂的 time.sleep,以保持适当的请求频率并低于限制。
import time
while next_url:
resp = requests.get(next_url, timeout=10)
resp.raise_for_status()
data = resp.json()
all_items.extend(data["results"])
next_url = data.get("next")
time.sleep(0.5) # 2 requests per second读取速率限制标头
规范的应用程序编程接口会通过 X-RateLimit-Remaining 和 X-RateLimit-Reset 等标头报告您的剩余配额。
您可以读取这些标头,只在接近限制时减慢请求速度,而不必始终等待。
remaining = int(resp.headers.get("X-RateLimit-Remaining", 1))
if remaining < 5:
reset = int(resp.headers.get("X-RateLimit-Reset", 1))
print("Near limit, sleeping", reset, "s")
time.sleep(reset)使用退避处理 429
如果确实遇到 429,响应通常会包含 Retry-After 标头,告知您需要等待多长时间。请在重试前遵守该等待时间。
resp = requests.get(url, timeout=10)
if resp.status_code == 429:
wait = int(resp.headers.get("Retry-After", 5))
time.sleep(wait)
resp = requests.get(url, timeout=10) # retry once使用 tqdm 显示进度条
没有反馈信息时,长时间运行的数据收集任务会让人感觉像是卡住了。tqdm 可以包装任何可迭代对象,并显示包含速率和 ETA 的实时进度条。
from tqdm import tqdm
for page in tqdm(range(1, 101), desc="Fetching"):
resp = requests.get(url, params={"page": page}, timeout=10)
all_items.extend(resp.json())
time.sleep(0.2)总数未知时使用 tqdm
对于游标分页,您事先不知道总数量。请将 tqdm 用作手动计数器,并在每次循环中调用 update()。
from tqdm import tqdm
pbar = tqdm(desc="Pages")
while next_url:
resp = requests.get(next_url, timeout=10)
data = resp.json()
all_items.extend(data["results"])
next_url = data.get("next")
pbar.update(1)
pbar.close()增量收集
对于超大数据集,不要将所有内容都保存在内存中。增量收集会在每个页面到达时将其写入磁盘,因此即使发生崩溃,也不会丢失全部进度。
import json
with open("items.jsonl", "w") as f:
while next_url:
resp = requests.get(next_url, timeout=10)
data = resp.json()
for item in data["results"]:
f.write(json.dumps(item) + "\n")
next_url = data.get("next")可恢复的收集
保存最后一个游标或页码,这样重新运行时就可以恢复,而不必从头开始。这会使长时间运行的任务具备容错能力。
import os
start_page = 1
if os.path.exists("checkpoint.txt"):
start_page = int(open("checkpoint.txt").read()) + 1
for page in range(start_page, 1000):
# ... fetch and store ...
open("checkpoint.txt", "w").write(str(page))整合起来
生产环境中的收集循环会整合所有部分:进行分页、遵守速率限制并等待、显示进度、增量写入,以及创建检查点。
from tqdm import tqdm
import time, json
with open("out.jsonl", "a") as f:
next_url = "https://api.example.com/items?limit=100"
pbar = tqdm(desc="Pages")
while next_url:
r = requests.get(next_url, timeout=10)
r.raise_for_status()
d = r.json()
for it in d["results"]:
f.write(json.dumps(it) + "\n")
next_url = d.get("next")
pbar.update(1)
time.sleep(0.3)快速检查:游标分页
应用程序编程接口会返回一个作为网址的 "next" 字段,最后一页则返回 None。
回顾:收集大型数据集
现在您已经可以收集跨越多个页面的数据集:
- 按页码分页和游标分页(
while next_url) - 使用
time.sleep和速率限制标头避免 429 - 受到限流时使用
Retry-After进行退避 - 使用
tqdm为长时间运行的任务显示进度条 - 使用可增量、可恢复的写入实现容错
接下来:高效存储收集到的数据。
常见问题解答
「分页与大型数据集采集」课时是免费的吗?
是的 — 「分页与大型数据集采集」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn AI with Python 课程的其余内容,请升级到 CoddyKit PRO。 Learn AI with Python 课程共包含 4 节课。
「分页与大型数据集采集」这节课中我会学到什么?
处理分页、next_cursor 模式,使用 time.sleep 实现速率限制,并显示进度条 你通过在浏览器中直接运行的动手代码来练习 Learn AI with Python,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Learn AI with Python 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Learn AI with Python 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「分页与大型数据集采集」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Learn AI with Python 课中编写并运行代码吗?
能。每节 Learn AI with Python 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 数据采集的 REST API 基础
- 分页与大型数据集采集
- 高效存储采集的数据
- 使用公共数据 API