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

Python调用Channel Advisor API分页获取全量数据失败求助

Channel Advisor API分页问题排查与解决方案

问题概述

调用Channel Advisor API时,Postman可正常获取包含@odata.nextLink的完整分页结果,但Python代码仅能获取前100条订单。尝试三个版本代码均存在问题:版本1循环仅执行一次;版本2返回400状态码;版本3触发JSONDecodeError。目标是将所有订单数据存入Pandas DataFrame。

API返回示例:

{
    "@odata.context": "https://api.channeladvisor.com/v1/$metadata#Orders",
    "value": [
        {....}
    ],
    "@odata.nextLink": "https://api.channeladvisor.com/v1/Orders?refresh_token=xxx&$skip=100"
}

各版本代码问题分析

版本1问题

  • 循环条件逻辑错误:判断'@odata.nextLink' in response_nextlink是检查字符串子串,而非响应中是否存在该键
  • 请求目标错误:循环中调用response_data['@odata.nextLink'],但response_data是订单数据列表,不存在该键,直接导致请求失败,循环终止
  • 数据追加错误:data.extend(response_data['value'])中,response_data已经是value列表,无需再取value属性

版本2问题

  • 认证冲突:@odata.nextLink中已包含refresh_token参数,但请求时仍携带Authorization头的Bearer Token,重复认证导致API返回400错误

版本3问题

  • 未处理请求失败场景:当请求返回非200状态码时(如认证过期、URL无效),响应内容不是JSON格式,直接调用response.json()触发JSONDecodeError

解决方案代码

import requests
import pandas as pd
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse

def get_access_token():
    url = 'https://api.channeladvisor.com/oauth2/token'
    headers = {'Authorization': 'Basic xxxxx'}
    post_body = {'grant_type': 'refresh_token', 'refresh_token': 'xxxxx'}
    response = requests.post(url, headers=headers, data=post_body)
    response.raise_for_status()
    return response.json()['access_token']

access_token = get_access_token()
base_url = 'https://api.channeladvisor.com/v1/orders'
headers = {
    'Authorization': f'Bearer {access_token}',
    'Accept': 'application/json'
}

data = []
current_url = base_url

while True:
    try:
        response = requests.get(current_url, headers=headers)
        response.raise_for_status()
        response_json = response.json()
        
        # 追加当前页数据
        page_data = response_json.get('value', [])
        if not page_data:
            break
        data.extend(page_data)
        
        # 检查下一页链接
        next_link = response_json.get('@odata.nextLink')
        if not next_link:
            break
        
        # 移除nextLink中的refresh_token参数,避免认证冲突
        parsed_url = urlparse(next_link)
        query_params = parse_qs(parsed_url.query)
        query_params.pop('refresh_token', None)
        new_query = urlencode(query_params, doseq=True)
        current_url = urlunparse(parsed_url._replace(query=new_query))
            
    except requests.exceptions.HTTPError as e:
        print(f"HTTP请求错误: {e}")
        break
    except ValueError as e:
        print(f"JSON解析错误: {e}")
        break

# 转换为DataFrame
df = pd.DataFrame(data)
print(f"共获取{len(df)}条订单数据")

关键优化点

  • 状态码检查:用response.raise_for_status()主动捕获HTTP错误,避免无效响应导致解析问题
  • 认证冲突处理:移除nextLink中的refresh_token参数,统一使用Bearer Token认证,解决400错误
  • 异常捕获:处理HTTP错误和JSON解析错误,避免程序直接崩溃
  • 安全取值:用get()方法获取value和@odata.nextLink,避免键不存在时的KeyError
  • 响应格式规范:将Accept设置为application/json,确保API返回JSON格式数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:28:16