分页接口通常返回 totalCount、pageSize、当页数据。需要全量数据时,用 while 循环按页请求即可。
Python 实现
按 totalCount 推进(稳定写法)
import math
page_size = 20
current = 1
all_items = []
while True:
params = {
"status": "ON_SALE",
"current": current,
"pageSize": page_size
}
response = fetchProductList(params)
data = response.get("model", [])
all_items.extend(data)
total_count = response.get("totalCount", 0)
total_pages = math.ceil(total_count / page_size)
print(f"已获取第 {current}/{total_pages} 页")
if current >= total_pages:
break
current += 1
print(f"总共获取 {len(all_items)} 条")
按当页数量判断末页(防 totalCount 不准)
如果接口的 totalCount 有时不准确,用当页返回数量是否小于 pageSize 来判断末页更稳:
page_size = 20
current = 1
all_items = []
while True:
params = {"status": "ON_SALE", "current": current, "pageSize": page_size}
response = fetchProductList(params)
items = response.get("model", [])
if not items:
break
all_items.extend(items)
print(f"获取第 {current} 页,{len(items)} 条")
if len(items) < page_size:
break
current += 1
生成器模式(内存友好)
适合商品数量很大、需要边翻页边处理的场景:
def iter_products():
current = 1
page_size = 20
while True:
resp = fetchProductList({
"status": "ON_SALE",
"current": current,
"pageSize": page_size
})
items = resp.get("model", [])
if not items:
break
yield from items
if len(items) < page_size:
break
current += 1
for item in iter_products():
print(item["title"])
JavaScript 实现
async/await 版本
async function getAllProducts() {
const pageSize = 20;
let current = 1;
const allItems = [];
while (true) {
const response = await fetchProductList({
status: "ON_SALE",
current,
pageSize
});
const items = response?.model || [];
if (items.length === 0) {
break;
}
allItems.push(...items);
console.log(`获取第 ${current} 页,${items.length} 条`);
if (items.length < pageSize) {
break;
}
current++;
}
console.log(`总共获取 ${allItems.length} 条`);
return allItems;
}
const products = await getAllProducts();
按 totalCount 计算总页数
async function getAllProducts() {
const pageSize = 20;
let current = 1;
let totalPages = 1;
const allItems = [];
while (current <= totalPages) {
const response = await fetchProductList({
status: "ON_SALE",
current,
pageSize
});
const items = response?.model || [];
allItems.push(...items);
totalPages = Math.ceil((response.totalCount || 0) / pageSize);
console.log(`获取第 ${current}/${totalPages} 页`);
current++;
}
return allItems;
}
流式处理(不存全量数据)
适合直接对每条数据执行操作(改价格、同步库存等),避免一次性把几千条数据加载到内存:
let current = 1;
const pageSize = 20;
while (true) {
const response = await fetchProductList({
status: "ON_SALE",
current,
pageSize
});
const items = response?.model || [];
if (!items.length) {
break;
}
for (const item of items) {
// 在这里处理每条商品
await updateStock(item.id, item.quantity);
}
if (items.length < pageSize) {
break;
}
current++;
}
两种终止条件对比
| 策略 | 适用场景 | 风险 |
|---|---|---|
current >= totalPages | totalCount 准确 | totalCount 不准时多/少请求 |
items.length < pageSize | 更通用 | 最后一页恰好整除时多一次空请求 |
两种可以结合使用:先按 totalPages 推进,同时检查当页数量作为保险。
