基于 Python 实现淘宝京东商品数据 API 批量获取

admin9小时前淘宝API8

在电商数据分析、竞品监控、选品优化、ERP系统对接等场景中,批量获取淘宝、京东平台的商品数据是高频需求。本文将从零开始,手把手教你用 Python 实现两大平台商品数据 API 的批量调用,涵盖前置准备、签名生成、代码封装、批量请求优化、数据解析全流程,提供可直接复制运行的代码,新手也能快速上手,避开平台调用坑点。

核心目标:通过 Python 封装淘宝、京东开放平台 API,实现多商品 ID 的批量数据抓取(支持商品标题、价格、库存、销量、图片等核心字段),解决批量调用中的限流、签名错误、数据解析混乱等常见问题,兼顾实用性和可扩展性。

一、前置准备(必做步骤)

批量调用淘宝、京东 API 的前提是完成开放平台的账号认证、应用创建和权限申请,这一步是基础,缺一不可,避免后续出现权限不足、签名失败等问题。

1.1 淘宝开放平台准备

  1. 注册并认证:访问 淘宝开放平台,注册开发者账号,完成个人/企业实名认证(企业认证可解锁更多接口权限,个人认证足够满足基础批量获取需求)。

  2. 创建应用:登录后进入「控制台」→「应用管理」→「新建应用」,填写应用名称、应用场景(如“电商数据采集”),提交审核(审核速度较快,一般1-2个工作日)。

  3. 获取核心参数:应用审核通过后,在应用详情页获取 AppKeyAppSecret(接口调用的核心凭证,请勿泄露)。

  4. 申请接口权限:在应用详情页→「接口管理」,搜索并申请以下两个核心接口(批量获取必备):

    1. taobao.item.get(单商品详情查询,基础接口,用于单个商品数据验证)

    2. taobao.item_get_batch(批量商品详情查询,核心接口,单次最多支持50个商品ID批量查询)

  5. 沙箱测试(可选):若担心正式环境调用出错,可开通沙箱环境,用沙箱账号、沙箱 AppKey 进行测试,避免触发正式环境限流。

1.2 京东开放平台准备

  1. 注册并认证:访问 京东开放平台(京东云·开放平台),注册开发者账号,完成实名认证。

  2. 创建应用:进入「开发者控制台」→「应用管理」→「创建应用」,选择应用类型(个人开发者选“第三方应用”),填写相关信息并提交审核。

  3. 获取核心参数:应用审核通过后,获取 AppKeyAppSecretAccessToken(京东 API 调用需额外获取 AccessToken,可通过平台提供的接口获取,有有效期,需定期刷新)。

  4. 申请接口权限:在应用详情页→「接口权限」,搜索并申请以下核心接口:

    1. jingdong.item.read.get(单商品详情查询,用于验证)

    2. jingdong.item.list.get(批量商品详情查询,核心接口,单次最多支持20个商品ID批量查询)

1.3 Python 环境准备

安装所需依赖库,直接执行以下命令(均为Python基础库,无需额外配置):

pip install requests # 发送HTTP请求,核心库 pip install jsonpath # 解析JSON数据(处理嵌套字段更便捷,可选) pip install tenacity # 实现重试机制,解决网络抖动、限流等问题

二、核心原理说明

淘宝、京东 API 调用的核心逻辑一致:构建请求参数 → 生成安全签名(防止请求被篡改) → 发送HTTP请求 → 解析返回的JSON数据 → 提取目标字段

关键注意点:

  • 签名机制:两大平台均要求对请求参数进行签名,签名规则略有差异,但核心都是“参数排序+密钥拼接+加密”,下文代码已封装好签名逻辑,直接替换自己的参数即可。

  • 限流控制:淘宝、京东 API 均有调用频次限制(如淘宝基础接口每分钟最多100次,京东单次批量查询不超过20个ID),批量调用时需控制并发和请求间隔,避免触发限流(429错误)。

  • 数据格式:返回数据均为JSON格式,部分字段嵌套较深,需用JSONPath或原生索引提取,下文会提供两种解析方式。

三、完整代码实现(可直接复制运行)

本文采用“类封装”方式,将淘宝、京东 API 的调用逻辑分别封装为独立类,便于后续扩展和维护,支持批量传入商品ID、自动处理签名、异常捕获和重试,最终输出结构化商品数据(可直接保存为CSV/Excel)。

3.1 通用工具类(签名、重试、异常处理)

import requests import hashlib import time from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type from requests.exceptions import RequestException import jsonpath class ApiUtils: """通用API工具类:封装签名生成、重试机制、异常处理""" @staticmethod def generate_sign(params, app_secret, platform="taobao"): """ 生成淘宝/京东API签名(核心方法) :param params: 请求参数(字典) :param app_secret: 应用密钥(AppSecret) :param platform: 平台(taobao/jd) :return: 签名字符串 """ # 按参数名ASCII码升序排列(两大平台均要求) sorted_params = sorted(params.items(), key=lambda x: x[0]) # 拼接参数字符串 sign_str = app_secret + "".join([f"{k}{v}" for k, v in sorted_params]) + app_secret # MD5加密,转大写(两大平台签名加密方式一致) sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest().upper() return sign @staticmethod @retry( stop=stop_after_attempt(3), # 最多重试3次 wait=wait_exponential(multiplier=1, min=1, max=5), # 指数退避:1s、2s、4s retry=retry_if_exception_type((RequestException, ConnectionError, TimeoutError)) ) def send_request(url, params=None, method="GET"): """ 发送HTTP请求,带重试机制 :param url: 请求地址 :param params: 请求参数 :param method: 请求方式(GET/POST) :return: 响应JSON数据 """ try: if method == "GET": response = requests.get(url, params=params, timeout=10) else: response = requests.post(url, data=params, timeout=10) response.raise_for_status() # 触发HTTP错误(如404、500) return response.json() except Exception as e: print(f"请求失败,原因:{str(e)},将进行重试") raise # 抛出异常,触发重试机制

3.2 淘宝API批量调用类

class TaobaoApiClient: def __init__(self, app_key, app_secret): """ 初始化淘宝API客户端 :param app_key: 淘宝AppKey :param app_secret: 淘宝AppSecret """ self.app_key = app_key self.app_secret = app_secret self.gateway = "https://eco.taobao.com/router/rest" # 淘宝API网关 self.common_params = { "app_key": self.app_key, "format": "json", "v": "2.0", "sign_method": "md5", "timestamp": time.strftime("%Y-%m-%d %H:%M:%S") # 实时时间戳 } def get_single_item(self, num_iid): """ 单个商品详情查询(用于验证) :param num_iid: 淘宝商品ID(从商品详情页URL提取) :return: 单个商品结构化数据 """ # 构建请求参数(公共参数+业务参数) params = { **self.common_params, "method": "taobao.item.get", "num_iid": num_iid, "fields": "num_iid,title,price,stock,volume,pic_url,brand,category" # 需返回的字段 } # 生成签名 params["sign"] = ApiUtils.generate_sign(params, self.app_secret, platform="taobao") # 发送请求 response = ApiUtils.send_request(self.gateway, params=params, method="GET") # 解析数据(处理异常场景) if "error_response" in response: raise Exception(f"淘宝API调用失败:{response['error_response']['msg']}") return self._parse_item_data(response["item"]) def batch_get_items(self, num_iids): """ 批量获取商品详情(核心方法) :param num_iids: 商品ID列表(最多50个) :return: 批量商品结构化数据列表 """ if len(num_iids) > 50: raise ValueError("淘宝批量查询单次最多支持50个商品ID") # 构建请求参数 params = { **self.common_params, "method": "taobao.item_get_batch", "item_ids": ",".join(num_iids), # 商品ID用逗号分隔 "fields": "num_iid,title,price,stock,volume,pic_url,brand,category" } # 生成签名 params["sign"] = ApiUtils.generate_sign(params, self.app_secret, platform="taobao") # 发送请求 response = ApiUtils.send_request(self.gateway, params=params, method="GET") # 解析数据 if "error_response" in response: raise Exception(f"淘宝批量API调用失败:{response['error_response']['msg']}") items = response.get("item_get_batch_response", {}).get("items", {}).get("item", []) return [self._parse_item_data(item) for item in items] @staticmethod def _parse_item_data(item): """解析商品数据,提取核心字段,返回结构化字典""" return { "platform": "taobao", "item_id": item.get("num_iid", ""), "title": item.get("title", ""), "price": float(item.get("price", 0.0)), # 价格转浮点数 "stock": int(item.get("stock", 0)), # 库存转整数 "sales": int(item.get("volume", 0)), # 销量转整数 "image_url": item.get("pic_url", ""), "brand": item.get("brand", ""), "category": item.get("category", "") }

3.3 京东API批量调用类

class JdApiClient: def __init__(self, app_key, app_secret, access_token): """ 初始化京东API客户端 :param app_key: 京东AppKey :param app_secret: 京东AppSecret :param access_token: 京东AccessToken(需定期刷新) """ self.app_key = app_key self.app_secret = app_secret self.access_token = access_token self.gateway = "https://api.jd.com/routerjson" # 京东API网关 self.common_params = { "app_key": self.app_key, "format": "json", "v": "2.0", "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), "access_token": self.access_token } def get_single_item(self, sku_id): """ 单个商品详情查询(用于验证) :param sku_id: 京东商品ID(从商品详情页URL提取) :return: 单个商品结构化数据 """ params = { **self.common_params, "method": "jingdong.item.read.get", "sku_id": sku_id, "fields": "sku_id,title,price,image_url,brand_info,category_info,sku_stock" } # 生成签名 params["sign"] = ApiUtils.generate_sign(params, self.app_secret, platform="jd") # 发送请求(京东API推荐用POST方式) response = ApiUtils.send_request(self.gateway, params=params, method="POST") # 解析数据 if "error_response" in response: raise Exception(f"京东API调用失败:{response['error_response']['msg']}") item = response.get("jingdong_item_read_get_response", {}).get("result", {}).get("item", {}) return self._parse_item_data(item) def batch_get_items(self, sku_ids): """ 批量获取商品详情(核心方法) :param sku_ids: 商品ID列表(最多20个) :return: 批量商品结构化数据列表 """ if len(sku_ids) > 20: raise ValueError("京东批量查询单次最多支持20个商品ID") params = { **self.common_params, "method": "jingdong.item.list.get", "sku_ids": ",".join(sku_ids), "fields": "sku_id,title,price,image_url,sku_stock" } # 生成签名 params["sign"] = ApiUtils.generate_sign(params, self.app_secret, platform="jd") # 发送请求 response = ApiUtils.send_request(self.gateway, params=params, method="POST") # 解析数据 if "error_response" in response: raise Exception(f"京东批量API调用失败:{response['error_response']['msg']}") items = response.get("jingdong_item_list_get_response", {}).get("result", {}).get("items", {}).get("item", []) return [self._parse_item_data(item) for item in items] @staticmethod def _parse_item_data(item): """解析京东商品数据,统一字段格式(与淘宝保持一致)""" return { "platform": "jd", "item_id": item.get("sku_id", ""), "title": item.get("title", ""), "price": float(item.get("price", 0.0)), "stock": int(item.get("sku_stock", 0)), "sales": 0, # 京东API需单独调用销量接口,此处暂设为0,可自行扩展 "image_url": item.get("image_url", ""), "brand": item.get("brand_info", {}).get("brand_name", ""), "category": item.get("category_info", {}).get("cid1_name", "") }

3.4 主程序(批量调用示例)

if __name__ == "__main__": # -------------------------- 配置参数(替换为自己的)-------------------------- # 淘宝配置 TAOBAO_APP_KEY = "你的淘宝AppKey" TAOBAO_APP_SECRET = "你的淘宝AppSecret" # 京东配置 JD_APP_KEY = "你的京东AppKey" JD_APP_SECRET = "你的京东AppSecret" JD_ACCESS_TOKEN = "你的京东AccessToken" # 批量商品ID(替换为自己需要查询的商品ID) TAOBAO_ITEM_IDS = ["520813250866", "123456789012", "987654321098"] # 最多50个 JD_ITEM_IDS = ["100012345678", "100087654321", "100098765432"] # 最多20个 try: # 1. 初始化客户端 taobao_client = TaobaoApiClient(TAOBAO_APP_KEY, TAOBAO_APP_SECRET) jd_client = JdApiClient(JD_APP_KEY, JD_APP_SECRET, JD_ACCESS_TOKEN) # 2. 批量获取淘宝商品数据 print("开始批量获取淘宝商品数据...") taobao_items = taobao_client.batch_get_items(TAOBAO_ITEM_IDS) print(f"淘宝商品数据获取完成,共{len(taobao_items)}个商品") # 3. 批量获取京东商品数据 print("\n开始批量获取京东商品数据...") jd_items = jd_client.batch_get_items(JD_ITEM_IDS) print(f"京东商品数据获取完成,共{len(jd_items)}个商品") # 4. 合并数据(可选),输出结构化结果 all_items = taobao_items + jd_items print("\n批量获取的所有商品数据:") for item in all_items: print(f"{item['platform']} | 商品ID:{item['item_id']} | 标题:{item['title']} | 价格:{item['price']}元 | 库存:{item['stock']}件") # 5. 保存数据到CSV(可选,便于后续分析) import csv with open("电商商品批量数据.csv", "w", encoding="utf-8-sig", newline="") as f: fieldnames = ["platform", "item_id", "title", "price", "stock", "sales", "image_url", "brand", "category"] writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() writer.writerows(all_items) print("\n数据已保存到:电商商品批量数据.csv") except Exception as e: print(f"程序执行失败:{str(e)}")

四、实战优化与避坑指南(重点)

很多开发者在批量调用 API 时,会遇到限流、签名错误、数据缺失等问题,以下优化方案和避坑点,能大幅提升程序稳定性和效率。

4.1 限流控制优化

  • 分批次调用:淘宝单次最多50个ID,京东单次最多20个ID,当需要查询的商品ID超过限制时,分批次调用,每批次之间添加间隔(如1-2秒),避免触发限流。 # 分批次处理京东商品ID(示例) jd_all_ids = ["100012345678", "100087654321", ...] # 假设100个ID batch_size = 20 # 京东单次最大批量数 for i in range(0, len(jd_all_ids), batch_size): batch_ids = jd_all_ids[i:i+batch_size] jd_items = jd_client.batch_get_items(batch_ids) time.sleep(1) # 每批次间隔1秒

  • 动态调整并发:若批量数据量极大(如1000个ID),可使用协程(aiohttp)实现并发调用,控制最大并发数(如30),提升效率的同时避免限流,具体代码可参考协程优化方案。

  • 限流后处理:若触发429限流错误,可通过响应头的X-RateLimit-Remaining字段,动态调整请求间隔和并发数,或添加更长时间的等待后重试。

4.2 常见坑点及解决方案

坑点

解决方案

签名错误(最常见)

1. 检查AppSecret大小写是否与平台一致;2. 确保参数字段按ASCII码升序排序;3. 时间戳与服务器时间差不超过5分钟;4. 避免参数值包含特殊字符(需URL编码)。

权限不足

1. 确认已申请对应接口权限;2. 个人认证接口权限有限,可升级为企业认证;3. 检查应用审核状态(需审核通过才能调用接口)。

数据解析失败(字段缺失)

1. 检查接口请求的fields参数,确保包含需要的字段;2. 部分商品可能缺失品牌、销量等字段,添加默认值(如0、空字符串);3. 复杂嵌套字段用JSONPath解析,避免索引报错。

AccessToken过期(京东专属)

1. 定期调用京东开放平台的token刷新接口,更新AccessToken;2. 在代码中添加token过期异常捕获,自动刷新并重新调用接口。

网络抖动导致请求失败

使用tenacity库实现重试机制,设置3-5次重试,指数退避等待,避免因临时网络问题导致程序中断。

4.3 功能扩展建议

  • 销量数据补充:京东API的基础批量接口不返回销量,可单独调用jingdong.sku.sales.get接口获取,整合到商品数据中。

  • 数据持久化:除了保存为CSV,可将数据存入MySQL、Redis等数据库,便于后续数据分析和查询。

  • 日志记录:添加日志模块(logging),记录每次API调用的状态、错误信息,便于问题排查。

  • 多平台适配:可扩展拼多多、亚马逊等其他电商平台的API调用,封装统一接口,实现多平台商品数据批量获取。

五、总结

本文完整实现了基于Python的淘宝、京东商品数据API批量获取,核心亮点的是:类封装设计便于扩展和维护,内置签名生成、重试机制、异常处理,解决了批量调用中的常见痛点,代码可直接复制替换参数运行,适合电商数据分析、竞品监控等多种场景。

需要注意的是,调用电商平台API时,需严格遵守平台的开发者规范,不得用于恶意爬取、违规数据采集等行为,避免应用被封禁。

如果在实际使用中遇到具体问题(如签名错误、权限申请、限流处理),可以在评论区留言,我会及时回复解答。

最后,觉得有用的话,记得点赞+收藏,关注我,后续会分享更多电商API实战、Python数据分析相关干货!


相关文章

淘宝商品评论API接口获取评论信息用户调研:item_review

淘宝商品评论API接口获取评论信息用户调研:item_review

 淘宝商品评论信息对于商家来说很重要,及时对商品评论数据进行分析,可以更好的根据客户需求改进商品,改进服务,从而提升业务。通过API可以实现批量自动化获取商品评论数据。item_review...

淘宝商品详情数据获取全方案分享

淘宝商品详情数据获取全方案分享

 编辑在电商数据分析、竞品监控、商品比价、选品决策、库存预警等场景中,淘宝商品详情数据是核心数据源——包含商品基础信息(标题、价格、主图)、规格参数(SKU、材质、尺寸)、营销信息(优惠、运...

高效提取淘宝商品数据:商品详情 API 的字段映射、解析逻辑与实战技巧

高效提取淘宝商品数据:商品详情 API 的字段映射、解析逻辑与实战技巧

 编辑最近帮几个做电商工具的朋友调淘宝商品详情 API,发现大家卡在同一个地方:明明拿到了返回数据,却总觉得用起来不顺手,要么是字段对应不上业务需求,要么是解析起来绕弯路。今天就结合实际操作...

淘宝商品详情API应用场景解析:获取实时的商品价格

淘宝商品详情API应用场景解析:获取实时的商品价格

 编辑在电商数字化运营体系中,商品价格是连接商家、平台与用户的核心枢纽,实时、准确的价格数据直接影响定价策略、用户转化与市场竞争力。淘宝商品详情API作为淘宝开放平台(TOP)提供的核心数据...

淘宝商品详情 API 接口 item_get:高效获取商品数据的技术方案

淘宝商品详情 API 接口 item_get:高效获取商品数据的技术方案

 编辑在电商数据开发、比价系统搭建、竞品分析工具开发等场景中,IT 技术员常面临 “如何稳定、合规地获取淘宝商品详情数据” 的难题 —— 传统爬虫不仅易触发反爬机制导致 IP 封禁,还需频繁...

抓取淘宝商品评论数据API调用实战分享

抓取淘宝商品评论数据API调用实战分享

 淘宝商品评论数据 API 核心用于市场分析、产品优化、运营决策等围绕电商生态的项目,具体落地场景如下:市场调研与竞品分析项目对比自身与竞品的评论关键词,挖掘用户对产品功能、价格、服务的核心...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。