做数据抓取或者对接第三方服务时,经常遇到API返回的数据是分页的。比如查订单、拉用户列表、读文章内容,一次拿不完,就得一页一页翻。很多人一开始不知道怎么处理,结果要么漏数据,要么重复请求,浪费资源。
常见的翻页方式有哪些?
先搞清楚对方API是怎么设计翻页的,主流方式就那么几种:
1. 基于页码(Page-based)
最常见的一种,每次请求带上 page 和 size 参数:
GET /api/users?page=2&size=10
这种好理解,就像翻书一样,第几页看多少条。但要注意页数可能动态变化,比如中途有数据插入,翻到后面可能会重复或跳过某些记录。
2. 基于偏移量(Offset-based)
用 offset 表示从第几条开始,limit 控制取多少:
GET /api/orders?offset=50&limit=20
适合小数据量场景。但数据越多,offset 越大,查询效率越低,数据库压力也大,很多系统在 offset 超过几千后就开始变慢。
3. 基于游标(Cursor-based)
更高效的做法,用上一次返回的“标记”作为下一次请求的起点。这个标记可能是时间戳、ID 或加密字符串:
GET /api/posts?cursor=1718923400
每次响应里会带一个 next_cursor,表示还有更多数据。这种方式不怕中间插入新数据,稳定性高,推荐优先使用。
实际代码怎么写?
以 Python 为例,用 requests 处理游标翻页:
import requests
cursor = None
all_data = []
while True:
params = {}
if cursor:
params['cursor'] = cursor
resp = requests.get('https://api.example.com/items', params=params)
data = resp.json()
items = data.get('items', [])
all_data.extend(items)
cursor = data.get('next_cursor')
if not cursor:
break # 没有下一页了
翻页时要注意这些坑
别以为只要一直翻就能搞定。有些API对频率有限制,一口气发几十个请求,可能直接被封IP。建议加个简单延迟:
import time
# ...
time.sleep(0.3) # 等300毫秒再发下一次
另外,记得检查返回状态码,万一中间哪次失败了,别傻乎乎继续往下跑。可以加个重试机制,失败两次后再报错。
什么时候该停?
不是所有数据都要拉完。比如你只关心最近7天的日志,那翻到时间戳超过7天前就可以收手了。设置合理的退出条件,省时间又省资源。
还有些API会告诉你 total_count,但别全信。有的只是估算值,特别是大数据量时。真要精确统计,得自己数一遍。
调试小技巧
刚开始对接时,先手动调一次接口,看看返回结构长什么样。可以用浏览器插件像 Postman,或者 curl 命令试试:
curl 'https://api.example.com/data?cursor=abc123'
看清楚字段名是 next_page 还是 hasNext,是 cursor 还是 token,别凭感觉写代码。
翻页这事看起来简单,实操起来细节一堆。搞明白了模式,写起脚本来就顺多了,数据也能拿得全、不重复。