分页 API 全量遍历:Python 与 JavaScript 实现模式

分页接口通常返回 totalCountpageSize、当页数据。需要全量数据时,用 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 >= totalPagestotalCount 准确totalCount 不准时多/少请求
items.length < pageSize更通用最后一页恰好整除时多一次空请求

两种可以结合使用:先按 totalPages 推进,同时检查当页数量作为保险。