You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从API拉取分页数据存入sqlite3并自动获取下一页

问题修复方案

问题1:数据库写入失败修复

你使用executemany方法时参数格式错误:executemany要求传入的第二个参数是由多行数据组成的可迭代对象,每一行数据对应一个包含占位符所需值的序列。你当前只传入了单个商品的字段列表,不符合方法要求。
修改方案:遍历生成的prodlist,把每个字典的字段按SQL占位符的顺序提取为元组,组成新的列表传给executemany即可。

问题2:特殊标识分页循环逻辑实现

你可以用一个变量存储当前的分页标识after,每次请求完成后提取返回的next_is_after:

  • 如果next_is_after有有效值,就用这个值构造新的请求端点,进入下一轮循环
  • 如果next_is_after为空/None,直接终止循环
完整可运行代码
import requests
import sqlite3

# 初始化数据库
con = sqlite3.connect('takealot.db')
cur = con.cursor()
cur.execute('''CREATE TABLE IF NOT EXISTS products
                    (sku text PRIMARY KEY, title text, slug text, reviews integer, star_rating real, listing_price real, pretty_price real)''')

baseurl = 'https://api.takealot.com/rest/v-1-10-0/searches/products,filters,facets,sort_options,breadcrumbs,slots_audience,context,seo'
# 初始分页标识,首次请求可以用这个值,不需要初始参数的话可以设为空字符串
current_after = "WzExNDEuMTYsNTYwNTkzNTFd"
# 加请求头避免被接口拦截
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

def main_request(baseurl, after_val, headers):
    endpoint = f"?after={after_val}" if after_val else ""
    res = requests.get(baseurl + endpoint, headers=headers)
    return res.json()

# 循环拉取所有页
while True:
    # 请求当前页数据
    daten = main_request(baseurl, current_after, headers)
    paging_info = daten['sections']['products']['paging']
    # 处理当前页数据
    prod_rows = []
    for data in daten['sections']['products']['results']:
        core_info = data['product_views']['core']
        buybox_info = data['product_views']['buybox_summary']
        prod_row = (
            core_info['id'],
            core_info['title'],
            core_info['slug'],
            core_info['reviews'],
            core_info['star_rating'],
            buybox_info['listing_price'],
            buybox_info['pretty_price']
        )
        prod_rows.append(prod_row)
    # 批量写入数据库
    cur.executemany("INSERT OR IGNORE INTO products VALUES (?, ?, ?, ?, ?, ?, ?)", prod_rows)
    con.commit()
    print(f"已写入{len(prod_rows)}条数据")
    # 判断是否有下一页
    next_is_after = paging_info.get('next_is_after')
    if not next_is_after:
        print("所有页拉取完成")
        break
    # 更新分页标识进入下一轮
    current_after = next_is_after

# 验证数据
for row in cur.execute('''SELECT * FROM products'''):
    print(row)

# 关闭数据库连接
cur.close()
con.close()

内容的提问来源于stack exchange,提问作者Jan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 16:36:03