做数据抓取或者对接第三方服务时,经常遇到API返回的数据是分页的。比如查订单、拉用户列表、获取商品信息,一次拿不完,就得一页一页翻。很多人一开始不知道怎么处理,结果要么漏数据,要么重复请求,白白浪费资源。
常见的翻页方式有哪些?
不同API设计不一样,翻页机制也五花八门。最常见的有三种:
1. 基于页码(Page-based)
这是最直观的一种:你告诉服务器要第几页,每页多少条。比如:
GET /api/users?page=2&size=10
这种好理解,但问题是总页数可能变,中途有数据增删,翻着翻着就乱了。
2. 基于偏移量(Offset-based)
和页码类似,但用的是从第几条开始:
GET /api/orders?offset=50&limit=25
适合小数据量,但数据越多越慢,因为数据库得跳过前面所有记录。
3. 基于游标(Cursor-based)
这才是真正靠谱的做法。每次返回下一页的“线索”,比如时间戳或ID:
GET /api/messages?cursor=1718923400
响应里会带上下一个 cursor:
{
"data": [...],
"next_cursor": "1718923300"
}
下一轮请求直接带上这个值,就能拿到后续数据。这种方式不怕中间数据变动,效率也高。
实际怎么写代码?
以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('data', [])
all_data.extend(items)
cursor = data.get('next_cursor')
if not cursor:
break # 没有下一页了
print(f'总共拿到 {len(all_data)} 条数据')
这段代码简单粗暴,但很实用。只要API支持cursor,基本不会出错。
遇到不规范的API怎么办?
有些老系统API没那么标准,比如只给当前页和总页数,甚至不告诉你有没有下一页。这时候可以加个判断:如果某一页返回数量少于设定的每页条数,基本就是最后一页了。
还有的API压根没翻页参数,但返回头里藏了线索。比如在 Link 头部用 rel="next" 提供下一页地址:
Link: <https://api.example.com/data?page=3>; rel="next", <https://api.example.com/data?page=5>; rel="last"
这时候别忘了看响应头,别死盯着 body。
别忘了控制节奏
翻页不是越快越好。频繁请求容易被限流甚至封IP。加个小小延迟很必要:
import time
# ...
time.sleep(0.3) # 每次请求间隔300毫秒
对对方服务器客气点,自己的程序也更稳定。
翻页看着小事,处理不好会影响整个数据流程。选对方式,写对逻辑,才能稳稳当当把数据拿全。