<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>万邦api博客</title><link>https://apiproxylog.com/</link><description>Good Luck To You!</description><item><title>中国制造网关键词搜索接口：业务过滤与分页偏移问题实战处理</title><link>https://apiproxylog.com/?id=226</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;uwJAiwRM&quot;&gt;前言&lt;/p&gt;&lt;p data-pid=&quot;vj3j8vcR&quot;&gt;中国制造网作为
 B2B 
外贸采购平台，关键词搜索接口和普通电商平台存在明显差异。接口返回数据混杂工厂、贸易商、中间商多种类型商家商品，同时存在分页偏移漂移、部分字段缺失、多语言字段混用等问题。网上多数示例只简单演示请求调用，缺少业务侧过滤逻辑。本文侧重工程落地，增加商家类型过滤、分页边界校验、结果数据清洗，给出可直接用于业务系统的调用示例。&lt;/p&gt;&lt;p data-pid=&quot;Nau6tFQv&quot;&gt;前置准备&lt;/p&gt;&lt;p data-pid=&quot;O4hvr7Jl&quot;&gt;对接前需要在平台开发者后台创建应用，获取&lt;code&gt;app_key&lt;/code&gt;、&lt;code&gt;app_secret&lt;/code&gt;，接口调用需要生成签名，同时获取访问令牌 access_token。接口有调用频次限制，B2B 平台对 QPS 管控严格，生产环境必须增加休眠限流，避免触发接口封禁。&lt;/p&gt;&lt;p data-pid=&quot;hhOPL8R3&quot;&gt;搜索接口入参核心：关键词、页码、每页条数、筛选条件；返回包含商品 ID、标题、价格、起订量、供应商信息、产地等字段。原始返回字段冗余，大量字段业务不需要，需要做裁剪处理。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://pic2.zhimg.com/80/v2-ee1f23f8f43ee18efe6e618ad0dbbf09_720w.jpg&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1159&quot; data-rawheight=&quot;688&quot; data-original-token=&quot;v2-349015b34a6bbec302bbfa014e07f5ed&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1159&quot; data-original=&quot;https://pic2.zhimg.com/v2-ee1f23f8f43ee18efe6e618ad0dbbf09_r.jpg&quot; data-actualsrc=&quot;https://pic2.zhimg.com/v2-ee1f23f8f43ee18efe6e618ad0dbbf09_1440w.jpg&quot; height=&quot;688&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;6aQm5Ho0&quot;&gt;&lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;点击获取key和secret&lt;/a&gt;&lt;/p&gt;&lt;p data-pid=&quot;ZfNA_VQ6&quot;&gt;核心 Python 代码示例&lt;/p&gt;&lt;p data-pid=&quot;zbL4Ps9v&quot;&gt;python&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests
import&amp;nbsp;time
import&amp;nbsp;hashlib

class&amp;nbsp;MadeInChinaSearchClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;app_secret,&amp;nbsp;access_token):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.access_token&amp;nbsp;=&amp;nbsp;access_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.base_url&amp;nbsp;=&amp;nbsp;&amp;quot;https://api.made‑in‑china.com/openapi/search/goods&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.session&amp;nbsp;=&amp;nbsp;requests.Session()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;gen_sign(self,&amp;nbsp;params):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sort_str&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;.join([f&amp;quot;{k}{v}&amp;quot;&amp;nbsp;for&amp;nbsp;k,&amp;nbsp;v&amp;nbsp;in&amp;nbsp;sorted(params.items())])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sign_raw&amp;nbsp;=&amp;nbsp;self.app_secret&amp;nbsp;+&amp;nbsp;sort_str&amp;nbsp;+&amp;nbsp;self.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.md5(sign_raw.encode(&amp;quot;utf‑8&amp;quot;)).hexdigest().upper()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;search_goods(self,&amp;nbsp;keyword,&amp;nbsp;page=1,&amp;nbsp;page_size=20,&amp;nbsp;factory_filter=True):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;access_token&amp;quot;:&amp;nbsp;self.access_token,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;keyword&amp;quot;:&amp;nbsp;keyword,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;page&amp;quot;:&amp;nbsp;page,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;page_size&amp;quot;:&amp;nbsp;page_size,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;timestamp&amp;quot;:&amp;nbsp;int(time.time())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params[&amp;quot;sign&amp;quot;]&amp;nbsp;=&amp;nbsp;self.gen_sign(params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;self.session.get(self.base_url,&amp;nbsp;params=params,&amp;nbsp;timeout=15)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res_json&amp;nbsp;=&amp;nbsp;resp.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;res_json.get(&amp;quot;code&amp;quot;)&amp;nbsp;!=&amp;nbsp;0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;error&amp;quot;:&amp;nbsp;res_json.get(&amp;quot;msg&amp;quot;),&amp;nbsp;&amp;quot;data&amp;quot;:&amp;nbsp;[]}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw_list&amp;nbsp;=&amp;nbsp;res_json.get(&amp;quot;data&amp;quot;,&amp;nbsp;{}).get(&amp;quot;goods_list&amp;quot;,&amp;nbsp;[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;item&amp;nbsp;in&amp;nbsp;raw_list:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;B2B业务过滤：只保留工厂类型供应商
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;supplier_type&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;supplier_type&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;factory_filter&amp;nbsp;and&amp;nbsp;supplier_type&amp;nbsp;!=&amp;nbsp;&amp;quot;factory&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clean_item&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;goods_id&amp;quot;:&amp;nbsp;item.get(&amp;quot;goods_id&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;item.get(&amp;quot;title&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;price&amp;quot;:&amp;nbsp;item.get(&amp;quot;price_range&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;moq&amp;quot;:&amp;nbsp;item.get(&amp;quot;min_order&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;supplier_name&amp;quot;:&amp;nbsp;item.get(&amp;quot;supplier_name&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;supplier_type&amp;quot;:&amp;nbsp;supplier_type
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.append(clean_item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(0.8)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;error&amp;quot;:&amp;nbsp;None,&amp;nbsp;&amp;quot;data&amp;quot;:&amp;nbsp;result}

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;MadeInChinaSearchClient(&amp;quot;your_key&amp;quot;,&amp;nbsp;&amp;quot;your_secret&amp;quot;,&amp;nbsp;&amp;quot;your_token&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ret&amp;nbsp;=&amp;nbsp;client.search_goods(&amp;quot;usb&amp;nbsp;charger&amp;quot;,&amp;nbsp;page=1,&amp;nbsp;factory_filter=True)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(ret[&amp;quot;data&amp;quot;])&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;PALZak09&quot;&gt;代码逻辑解读&lt;/p&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;封装请求类统一管理签名、会话、限流休眠，避免重复代码；签名按照平台规则对参数排序后 MD5 加密。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;增加&lt;code&gt;factory_filter&lt;/code&gt;开关，B2B 场景经常只需要工厂货源，过滤贸易商数据，减少后续业务处理压力。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;做数据裁剪，剔除大量无用返回字段，只保留业务核心字段，降低内存占用。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;增加超时、错误码判断，简单休眠控制 QPS，防止短时间高频调用被限制。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p data-pid=&quot;6t9twgHD&quot;&gt;线上踩坑总结&lt;/p&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;分页漂移&lt;/strong&gt;：平台搜索结果会实时变化，翻页时会出现重复商品，业务层需要用 goods_id 做去重，不能单纯依赖分页。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;价格字段为空&lt;/strong&gt;：部分商品不公开报价，price_range 会返回 null，业务代码要做空值判断，直接取值会抛出异常。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;供应商类型字段不稳定&lt;/strong&gt;：部分老商品供应商类型字段缺失，需要做好兜底。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;令牌过期&lt;/strong&gt;：access_token 具备有效期，生产环境需要增加自动刷新逻辑，示例中未展示。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Thu, 27 Aug 2026 15:11:03 +0800</pubDate></item><item><title>中国制造网商品详情接口：B2B 供应商属性结构化解析实践</title><link>https://apiproxylog.com/?id=225</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;xZ-vyKat&quot;&gt;前言&lt;/p&gt;&lt;p data-pid=&quot;3aGXhi8k&quot;&gt;网上多数教程只简单演示接口调用，直接打印原始返回结果，忽略中国制造网
 B 端独有的业务特征：供应商资质、MOQ 
起订量、包装参数、产地、定制加工属性。原始接口返回嵌套层级深，大量字段为平台内部使用，直接入库会产生大量冗余数据。本文不从简单请求示例入手，重点讲解&lt;strong&gt;字段过滤、供应商信息剥离、异常场景兼容&lt;/strong&gt;，适配比价、供应链数据同步业务。&lt;/p&gt;&lt;p data-pid=&quot;p-5SFtKn&quot;&gt;前置准备&lt;/p&gt;&lt;p data-pid=&quot;zxr7Mhup&quot;&gt;登录中国制造开放平台创建应用，获取 appKey、appSecret，完成授权拿到 access_token。调用商品详情接口传入产品 ID，需要区分公开商品、会员专属商品，后者会返回权限异常，代码层面必须做拦截处理。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://pic1.zhimg.com/80/v2-17b2aae52ead7c25871290b4ce2f3c78_720w.webp&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1165&quot; data-rawheight=&quot;576&quot; data-original-token=&quot;v2-281cf7ee19bc8129996e060757cc7268&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1165&quot; data-original=&quot;https://pic1.zhimg.com/v2-17b2aae52ead7c25871290b4ce2f3c78_r.jpg&quot; data-actualsrc=&quot;https://pic1.zhimg.com/v2-17b2aae52ead7c25871290b4ce2f3c78_1440w.jpg&quot; height=&quot;576&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;h5J_fDmj&quot;&gt;&lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;点击获取key和secret&lt;/a&gt;&lt;/p&gt;&lt;p data-pid=&quot;0EFNx-Hi&quot;&gt;核心 Python 代码示例&lt;/p&gt;&lt;p data-pid=&quot;IJST_F7F&quot;&gt;python&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests

class&amp;nbsp;MadeInChinaDetailClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;access_token):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.token&amp;nbsp;=&amp;nbsp;access_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.api_url&amp;nbsp;=&amp;nbsp;&amp;quot;https://api.made‑in‑china.com/openapi/product/detail/get&amp;quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;fetch_product_detail(self,&amp;nbsp;product_id):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;payload&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;appKey&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;accessToken&amp;quot;:&amp;nbsp;self.token,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;productId&amp;quot;:&amp;nbsp;product_id
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;requests.get(self.api_url,&amp;nbsp;params=payload,&amp;nbsp;timeout=18)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;origin_data&amp;nbsp;=&amp;nbsp;resp.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.struct_data(origin_data)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;struct_data(self,&amp;nbsp;raw):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;数据结构化：剥离供应商、定制属性，过滤无用字段&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;ok&amp;quot;:&amp;nbsp;False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;product_id&amp;quot;:&amp;nbsp;None,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;main_img&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;moq&amp;quot;:&amp;nbsp;0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;origin_place&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_custom&amp;quot;:&amp;nbsp;False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;supplier_info&amp;quot;:&amp;nbsp;{},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;msg&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;raw.get(&amp;quot;code&amp;quot;)&amp;nbsp;!=&amp;nbsp;0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;msg&amp;quot;]&amp;nbsp;=&amp;nbsp;raw.get(&amp;quot;message&amp;quot;,&amp;nbsp;&amp;quot;接口调用失败&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;output
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data&amp;nbsp;=&amp;nbsp;raw.get(&amp;quot;data&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;data:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;msg&amp;quot;]&amp;nbsp;=&amp;nbsp;&amp;quot;商品不存在或已下架&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;output
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;product&amp;nbsp;=&amp;nbsp;data.get(&amp;quot;productInfo&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;supplier&amp;nbsp;=&amp;nbsp;data.get(&amp;quot;supplierInfo&amp;quot;,&amp;nbsp;{})

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;ok&amp;quot;]&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;product_id&amp;quot;]&amp;nbsp;=&amp;nbsp;product.get(&amp;quot;productId&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;title&amp;quot;]&amp;nbsp;=&amp;nbsp;product.get(&amp;quot;productName&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;main_img&amp;quot;]&amp;nbsp;=&amp;nbsp;product.get(&amp;quot;mainImageUrl&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;moq&amp;quot;]&amp;nbsp;=&amp;nbsp;product.get(&amp;quot;minOrderQuantity&amp;quot;,&amp;nbsp;0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;origin_place&amp;quot;]&amp;nbsp;=&amp;nbsp;product.get(&amp;quot;origin&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;is_custom&amp;quot;]&amp;nbsp;=&amp;nbsp;bool(product.get(&amp;quot;supportCustomize&amp;quot;,&amp;nbsp;0))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;提取供应商核心业务字段
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output[&amp;quot;supplier_info&amp;quot;]&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;company_name&amp;quot;:&amp;nbsp;supplier.get(&amp;quot;companyName&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;factory_type&amp;quot;:&amp;nbsp;supplier.get(&amp;quot;factoryType&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;certification&amp;quot;:&amp;nbsp;supplier.get(&amp;quot;certList&amp;quot;,&amp;nbsp;[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;output

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;MadeInChinaDetailClient(&amp;quot;your_appkey&amp;quot;,&amp;nbsp;&amp;quot;your_access_token&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;=&amp;nbsp;client.fetch_product_detail(product_id=95******21)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(res)&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;4M70vPta&quot;&gt;代码逻辑解析&lt;/p&gt;&lt;p data-pid=&quot;4qPwjw8W&quot;&gt;核心在于&lt;code&gt;struct_data&lt;/code&gt;结构化函数，不直接透传原始 JSON。&lt;/p&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;优先拦截接口错误码，区分鉴权失败、商品下架、权限不足；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;将商品基础参数、供应商信息做分离，业务系统可以分开存储产品表与供应商表；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;识别是否支持定制加工、最小起订量、产地等 B2B 关键业务字段；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;返回固定结构体，上层业务无需关心原始接口字段变动。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p data-pid=&quot;Bs4ajAPK&quot;&gt;对接踩坑汇总&lt;/p&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;access_token 存在有效期，批量同步商品时，捕获鉴权报错，触发 token 重新获取逻辑；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;部分 OEM 定制类商品无固定售价，价格字段为空，业务代码必须做空值判断；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;开放平台存在 QPS 限制，大批量拉取需要做批次休眠，高频调用会被限流；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;部分仅对采购会员开放的商品，即便产品 ID 正确，也无法获取详情，需要标记异常，不要直接抛出程序崩溃。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Tue, 25 Aug 2026 16:45:34 +0800</pubDate></item><item><title>1688 商品详情接口：多规格价格分层解析与业务数据归一化实践</title><link>https://apiproxylog.com/?id=224</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;Zyo24_u1&quot;&gt;前言&lt;/p&gt;&lt;p data-pid=&quot;kMgjbmHY&quot;&gt;大部分公开教程只演示简单调用获取商品基础信息，忽略
 1688B 端核心痛点：阶梯批发价、多 SKU 
规格、起订量限制、混批规则字段杂乱。同一商品会存在多档拿货价，原始接口返回字段嵌套层级深，直接拿原始 JSON 
很难直接用于业务系统。本文重点不是简单请求演示，而是对接入后的数据做分层解析、脏字段过滤，适配采购、比价类业务场景。&lt;/p&gt;&lt;p data-pid=&quot;8qhOZ4sS&quot;&gt;前置准备&lt;/p&gt;&lt;p data-pid=&quot;v_JuHjLW&quot;&gt;调用前需要在 1688 开放平台创建应用，获取 appKey、appSecret，拿到 access_token。商品详情接口需要传入商品 ID，注意部分私密商品、被下架商品会返回权限类异常，业务代码必须做兼容处理。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://pic4.zhimg.com/80/v2-a590c361f35e19e3e419c9a682b78699_720w.jpg&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1163&quot; data-rawheight=&quot;576&quot; data-original-token=&quot;v2-2312f1dedaf94d223c136cd718cf4608&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1163&quot; data-original=&quot;https://pic4.zhimg.com/v2-a590c361f35e19e3e419c9a682b78699_r.jpg&quot; data-actualsrc=&quot;https://pic4.zhimg.com/v2-a590c361f35e19e3e419c9a682b78699_1440w.jpg&quot; height=&quot;576&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;swoAK8uD&quot;&gt;&lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;点击获取key和secret&lt;/a&gt;&lt;/p&gt;&lt;p data-pid=&quot;3nC69vmo&quot;&gt;核心 Python 代码示例&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests
import&amp;nbsp;time

class&amp;nbsp;Ali1688DetailClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;app_secret,&amp;nbsp;access_token):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.token&amp;nbsp;=&amp;nbsp;access_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.url&amp;nbsp;=&amp;nbsp;&amp;quot;https://gw.open.1688.com/openapi/param2/1/com.alibaba.trade/alibaba.trade.getProductDetail&amp;quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product_detail(self,&amp;nbsp;product_id):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;appKey&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;access_token&amp;quot;:&amp;nbsp;self.token,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;productId&amp;quot;:&amp;nbsp;product_id
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;requests.get(self.url,&amp;nbsp;params=params,&amp;nbsp;timeout=15)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw_data&amp;nbsp;=&amp;nbsp;resp.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;self.data_normalize(raw_data)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;data_normalize(self,&amp;nbsp;raw):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;核心：原始数据归一化，提取阶梯价格、起订量，过滤无效字段&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;success&amp;quot;:&amp;nbsp;False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;product_id&amp;quot;:&amp;nbsp;None,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;main_image&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;price_list&amp;quot;:&amp;nbsp;[],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;min_order&amp;quot;:&amp;nbsp;0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_off_shelf&amp;quot;:&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;raw.get(&amp;quot;errorCode&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;msg&amp;quot;]&amp;nbsp;=&amp;nbsp;raw.get(&amp;quot;errorMessage&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;res
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data&amp;nbsp;=&amp;nbsp;raw.get(&amp;quot;result&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;data&amp;nbsp;or&amp;nbsp;data.get(&amp;quot;status&amp;quot;)&amp;nbsp;!=&amp;nbsp;&amp;quot;success&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;msg&amp;quot;]&amp;nbsp;=&amp;nbsp;&amp;quot;商品数据为空或已下架&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;is_off_shelf&amp;quot;]&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;res
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;info&amp;nbsp;=&amp;nbsp;data.get(&amp;quot;productInfo&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;success&amp;quot;]&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;product_id&amp;quot;]&amp;nbsp;=&amp;nbsp;info.get(&amp;quot;productId&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;title&amp;quot;]&amp;nbsp;=&amp;nbsp;info.get(&amp;quot;subject&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;main_image&amp;quot;]&amp;nbsp;=&amp;nbsp;info.get(&amp;quot;mainImage&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;min_order&amp;quot;]&amp;nbsp;=&amp;nbsp;info.get(&amp;quot;minOrderQuantity&amp;quot;,&amp;nbsp;0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;解析批发阶梯价格
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;price_steps&amp;nbsp;=&amp;nbsp;info.get(&amp;quot;priceRanges&amp;quot;,&amp;nbsp;[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;p&amp;nbsp;in&amp;nbsp;price_steps:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res[&amp;quot;price_list&amp;quot;].append({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;start_num&amp;quot;:&amp;nbsp;p.get(&amp;quot;startQuantity&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;price&amp;quot;:&amp;nbsp;p.get(&amp;quot;price&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;res

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;Ali1688DetailClient(&amp;quot;your_appkey&amp;quot;,&amp;quot;your_secret&amp;quot;,&amp;quot;your_token&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detail&amp;nbsp;=&amp;nbsp;client.get_product_detail(product_id=68******56)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(detail)&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;dsCYBTa0&quot;&gt;代码逻辑解析&lt;/p&gt;&lt;p data-pid=&quot;vfJ-x3Iz&quot;&gt;data_normalize 函数是整套封装的重点。接口原始返回字段繁多，很多是平台内部使用字段，全部存储会浪费存储空间。这里只提取业务需要的标题、主图、起订量、多档批发价格。&lt;/p&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;优先捕获 errorCode，处理鉴权错误、token 过期；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;判断商品状态，识别下架、删除商品；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;循环解析 priceRanges，把阶梯批发价整理成结构化数组，方便前端展示或者入库；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;返回统一格式结构体，上层业务不需要感知原始接口字段变化。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p data-pid=&quot;0izVMLEU&quot;&gt;对接过程常见问题&lt;/p&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;Token 短期有效，大批量循环获取商品详情时，要做好 token 过期捕获与自动刷新逻辑；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;部分定制类商品没有阶梯价格，priceRanges 为空数组，业务上要做空判断，避免程序报错；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;平台有调用频率限制，短时间大量请求会触发限流，建议增加 sleep 间隔，按批次拉取；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;私密商品、分销商专属商品，即便 ID 正确也无法获取详情，代码需要标记该类异常，不要直接抛出崩溃。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Mon, 24 Aug 2026 16:18:47 +0800</pubDate></item><item><title>1688 店铺列表搜索接口：B 端供应商检索的分页偏移与脏数据过滤方案</title><link>https://apiproxylog.com/?id=223</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;4-NbaM2f&quot;&gt;1688 
店铺搜索接口多用于供应商挖掘、同行店铺盘点。网上大部分示例只演示基础签名与循环分页，忽略 B 
端特有问题：搜索结果会混入关闭店铺、个体散户，并且服务端动态权重排序会造成分页偏移，同一店铺多次重复出现，直接循环翻页会造成统计结果失真。本文不做基础参数科普，聚焦业务层过滤、偏移去重、异常兼容，提供一套面向供应商筛选的生产级封装代码。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://picx.zhimg.com/80/v2-e62ac34709130eed9296de1558335cdb_720w.jpg&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1198&quot; data-rawheight=&quot;597&quot; data-original-token=&quot;v2-2053e7a5ddfa2cfc5c6a46eaaa30f845&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1198&quot; data-original=&quot;https://picx.zhimg.com/v2-e62ac34709130eed9296de1558335cdb_r.jpg&quot; data-actualsrc=&quot;https://picx.zhimg.com/v2-e62ac34709130eed9296de1558335cdb_1440w.jpg&quot; height=&quot;597&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;PNBal-Ur&quot;&gt;该接口核心痛点：total 总计数仅供参考，超过一定页码后统计值不准；部分店铺已经停业注销，但接口依然返回记录；翻页过程平台实时重排，造成店铺重复；中文关键词必须做好编码，否则签名直接报错。开发前需要在开放平台申请对应接口权限，获取 &lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;app_key、app_secret&lt;/a&gt;，服务器 IP 加入白名单。&lt;/p&gt;&lt;p data-pid=&quot;j2otXksb&quot;&gt;python&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests
import&amp;nbsp;time
import&amp;nbsp;hashlib

class&amp;nbsp;Ali1688ShopSearch:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;app_secret):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.api_url&amp;nbsp;=&amp;nbsp;&amp;quot;https://gw.open.1688.com/openapi/http&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.shop_member_set&amp;nbsp;=&amp;nbsp;set()&amp;nbsp;#&amp;nbsp;店铺memberId全局去重，解决分页偏移
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.session&amp;nbsp;=&amp;nbsp;requests.Session()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;make_sign(self,&amp;nbsp;params):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sorted_param&amp;nbsp;=&amp;nbsp;sorted(params.items(),&amp;nbsp;key=lambda&amp;nbsp;x:x[0])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw_str&amp;nbsp;=&amp;nbsp;self.app_secret&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;quot;.join(f&amp;quot;{k}{v}&amp;quot;&amp;nbsp;for&amp;nbsp;k,v&amp;nbsp;in&amp;nbsp;sorted_param)&amp;nbsp;+&amp;nbsp;self.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.md5(raw_str.encode(&amp;quot;utf-8&amp;quot;)).hexdigest().upper()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;query_single_page(self,&amp;nbsp;keyword,&amp;nbsp;page_no,&amp;nbsp;page_size=20):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timestamp&amp;nbsp;=&amp;nbsp;str(int(time.time()*1000))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;method&amp;quot;:&amp;nbsp;&amp;quot;alibaba.seller.search&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;timestamp&amp;quot;:&amp;nbsp;timestamp,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;format&amp;quot;:&amp;nbsp;&amp;quot;json&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;v&amp;quot;:&amp;nbsp;&amp;quot;2.0&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;q&amp;quot;:&amp;nbsp;keyword,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pageNo&amp;quot;:&amp;nbsp;page_no,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pageSize&amp;quot;:&amp;nbsp;min(page_size,20)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params[&amp;quot;sign&amp;quot;]&amp;nbsp;=&amp;nbsp;self.make_sign(params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;self.session.post(self.api_url,&amp;nbsp;data=params,&amp;nbsp;timeout=12)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;resp.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;search_shop_list(self,&amp;nbsp;keyword,&amp;nbsp;max_page=30):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_result&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;page&amp;nbsp;=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;page&amp;nbsp;&amp;lt;=&amp;nbsp;max_page:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(1.0)&amp;nbsp;#&amp;nbsp;QPS限流适配
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp_json&amp;nbsp;=&amp;nbsp;self.query_single_page(keyword,&amp;nbsp;page)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp_body&amp;nbsp;=&amp;nbsp;resp_json.get(&amp;quot;alibaba_seller_search_response&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_list&amp;nbsp;=&amp;nbsp;resp_body.get(&amp;quot;sellerList&amp;quot;,&amp;nbsp;[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;shop_list:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;shop&amp;nbsp;in&amp;nbsp;shop_list:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;member_id&amp;nbsp;=&amp;nbsp;shop.get(&amp;quot;memberId&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;member_id&amp;nbsp;or&amp;nbsp;member_id&amp;nbsp;in&amp;nbsp;self.shop_member_set:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;过滤停业、无效店铺
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;shop.get(&amp;quot;isClosed&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.shop_member_set.add(member_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_result.append({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;member_id&amp;quot;:&amp;nbsp;member_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;shop_name&amp;quot;:&amp;nbsp;shop.get(&amp;quot;shopName&amp;quot;,&amp;quot;&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;company_name&amp;quot;:&amp;nbsp;shop.get(&amp;quot;companyName&amp;quot;,&amp;quot;&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_factory&amp;quot;:&amp;nbsp;shop.get(&amp;quot;isFactory&amp;quot;,False),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;credit_level&amp;quot;:&amp;nbsp;shop.get(&amp;quot;creditLevel&amp;quot;,&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;page&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;valid_shop_count&amp;quot;:&amp;nbsp;len(shop_result),&amp;nbsp;&amp;quot;shop_data&amp;quot;:&amp;nbsp;shop_result}

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;Ali1688ShopSearch(&amp;quot;your_app_key&amp;quot;,&amp;quot;your_app_secret&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;=&amp;nbsp;client.search_shop_list(&amp;quot;五金配件&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;筛选后有效供应商数量：&amp;quot;,&amp;nbsp;res[&amp;quot;valid_shop_count&amp;quot;])&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;bx3lwZx4&quot;&gt;代码做三处差异化处理：第一，以 memberId 作为唯一标识，集合全局去重，专门解决 B 端动态排序带来的分页偏移重复；第二，增加停业店铺过滤，剔除已经失效的供应商；第三，设置最大页码保护，避免 total 计数不准造成无限空跑。&lt;/p&gt;&lt;p data-pid=&quot;ImmMz8dk&quot;&gt;对接调试要点：签名报错优先核对参数排序、毫秒时间戳；中文关键词不需要手动编码，底层请求库自动处理；不要去掉 sleep，平台会按 app_key 做限流。total 字段仅做参考，业务统计以实际返回并过滤后的数据集为准。&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Fri, 21 Aug 2026 17:29:26 +0800</pubDate></item><item><title>唯品会关键词搜索接口：特卖场景下分页漂移与数据归一化实践</title><link>https://apiproxylog.com/?id=222</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;QXN54y2A&quot;&gt;唯品会以特卖闪购为核心，其开放平台关键词搜索接口和普通电商逻辑差异很大。网上多数示例只演示基础调用，忽略特卖商品实时上下架带来的&lt;strong&gt;分页漂移、结果重复、混入过期专场商品&lt;/strong&gt;等生产问题，直接上线会出现数据重复、统计失真。本文不从基础参数讲解切入，聚焦业务侧的去重、异常过滤、签名容错，给出一套可用于选品分析的封装实现。&lt;/p&gt;&lt;p data-pid=&quot;AGe81_uE&quot;&gt;该接口最大的坑点并非签名本身，而是业务层面：特卖商品会动态上下架，翻页过程中排序发生变动，同一商品会出现在多个页码；同时接口会返回已经结束特卖的商品，如果不做过滤，业务统计会引入大量无效数据。另外时间戳必须使用
 13 位毫秒，时间偏差过大会直接鉴权失败，很多示例没有做校验处理。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://pic3.zhimg.com/80/v2-c3a87edcce08de6a6d3f70c2c94214dc_720w.webp&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1189&quot; data-rawheight=&quot;700&quot; data-original-token=&quot;v2-86312f63e89c776cd02067bb57d0ddc2&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1189&quot; data-original=&quot;https://pic3.zhimg.com/v2-c3a87edcce08de6a6d3f70c2c94214dc_r.jpg&quot; data-actualsrc=&quot;https://pic3.zhimg.com/v2-c3a87edcce08de6a6d3f70c2c94214dc_1440w.jpg&quot; height=&quot;700&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;HKAe-R1e&quot;&gt;前置条件：完成开放平台企业认证，申请搜索接口权限，获取 &lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;app_key、app_secret&lt;/a&gt;，服务器 IP 加入白名单。&lt;/p&gt;&lt;p data-pid=&quot;j_9NZyJK&quot;&gt;python&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests
import&amp;nbsp;time
import&amp;nbsp;hashlib

class&amp;nbsp;VipKeywordSearch:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;app_secret):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.api_url&amp;nbsp;=&amp;nbsp;&amp;quot;https://openapi.vip.com/router/rest&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.item_set&amp;nbsp;=&amp;nbsp;set()&amp;nbsp;&amp;nbsp;#&amp;nbsp;用于去重，解决分页漂移
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.session&amp;nbsp;=&amp;nbsp;requests.Session()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;build_sign(self,&amp;nbsp;params):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;唯品会签名：按键名ASCII升序排序
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sorted_items&amp;nbsp;=&amp;nbsp;sorted(params.items(),&amp;nbsp;key=lambda&amp;nbsp;x:&amp;nbsp;x[0])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw&amp;nbsp;=&amp;nbsp;self.app_secret&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;quot;.join(f&amp;quot;{k}{v}&amp;quot;&amp;nbsp;for&amp;nbsp;k,&amp;nbsp;v&amp;nbsp;in&amp;nbsp;sorted_items)&amp;nbsp;+&amp;nbsp;self.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.md5(raw.encode(&amp;quot;utf‑8&amp;quot;)).hexdigest().upper()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;query_page(self,&amp;nbsp;keyword,&amp;nbsp;page,&amp;nbsp;page_size=20):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timestamp&amp;nbsp;=&amp;nbsp;str(int(time.time()&amp;nbsp;*&amp;nbsp;1000))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;appKey&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;method&amp;quot;:&amp;nbsp;&amp;quot;vip.item.search&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;timestamp&amp;quot;:&amp;nbsp;timestamp,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;format&amp;quot;:&amp;nbsp;&amp;quot;json&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;v&amp;quot;:&amp;nbsp;&amp;quot;1.0&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;keyword&amp;quot;:&amp;nbsp;keyword,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pageNo&amp;quot;:&amp;nbsp;page,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pageSize&amp;quot;:&amp;nbsp;min(page_size,20)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params[&amp;quot;sign&amp;quot;]&amp;nbsp;=&amp;nbsp;self.build_sign(params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;self.session.post(self.api_url,&amp;nbsp;data=params,&amp;nbsp;timeout=10)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;resp.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;search_all(self,&amp;nbsp;keyword):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result_list&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;page&amp;nbsp;=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;True:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(1.2)&amp;nbsp;#&amp;nbsp;适配平台QPS限制
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp_data&amp;nbsp;=&amp;nbsp;self.query_page(keyword,&amp;nbsp;page)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp_body&amp;nbsp;=&amp;nbsp;resp_data.get(&amp;quot;vip_item_search_response&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item_list&amp;nbsp;=&amp;nbsp;resp_body.get(&amp;quot;itemList&amp;quot;,&amp;nbsp;[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;item_list:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;item&amp;nbsp;in&amp;nbsp;item_list:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item_id&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;itemId&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;item_id&amp;nbsp;or&amp;nbsp;item_id&amp;nbsp;in&amp;nbsp;self.item_set:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;过滤已结束特卖的商品
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;item.get(&amp;quot;isOnSale&amp;quot;)&amp;nbsp;!=&amp;nbsp;1:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.item_set.add(item_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result_list.append({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;item_id&amp;quot;:&amp;nbsp;item_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;item.get(&amp;quot;title&amp;quot;,&amp;quot;&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sale_price&amp;quot;:&amp;nbsp;item.get(&amp;quot;salePrice&amp;quot;,0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;original_price&amp;quot;:&amp;nbsp;item.get(&amp;quot;originalPrice&amp;quot;,0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;brand&amp;quot;:&amp;nbsp;item.get(&amp;quot;brandName&amp;quot;,&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;resp_body.get(&amp;quot;total&amp;quot;,0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;page&amp;nbsp;*&amp;nbsp;20&amp;nbsp;&amp;gt;=&amp;nbsp;total:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;page&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;count&amp;quot;:&amp;nbsp;len(result_list),&amp;nbsp;&amp;quot;goods&amp;quot;:&amp;nbsp;result_list}

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;VipKeywordSearch(&amp;quot;your_app_key&amp;quot;,&amp;quot;your_app_secret&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;=&amp;nbsp;client.search_all(&amp;quot;女士连衣裙&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;有效在售商品数量：&amp;quot;,&amp;nbsp;res[&amp;quot;count&amp;quot;])&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;E6OwnNNP&quot;&gt;代码中核心做了三处业务优化：第一，使用 set 集合保存商品 ID，专门解决特卖场景分页漂移带来的数据重复；第二，增加&lt;code&gt;isOnSale&lt;/code&gt;状态过滤，剔除专场结束的失效商品；第三，控制请求间隔，避免触发平台限流风控。&lt;/p&gt;&lt;p data-pid=&quot;qrQLCgF-&quot;&gt;对接调试常见问题：签名报错优先检查参数排序、毫秒时间戳、密钥前后有无空格；返回结果为空，排查 IP 白名单、接口权限是否开通；批量采集时不可去掉 sleep，平台会按 app_key+IP 双重限流。&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Thu, 20 Aug 2026 17:48:12 +0800</pubDate></item><item><title>京东店铺全量商品接口：分页边界修复与数据完整性采集方案</title><link>https://apiproxylog.com/?id=221</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;yyb69asL&quot;&gt;京东店铺商品列表接口（jd.union.open.shop.goods.get）是竞品店铺盘点、铺货监控、店铺商品巡检的核心接口。网上绝大多数教程仅实现基础分页循环调用，完全忽略平台隐性限制：接口存在100页分页上限、超页返回空数据、上下架商品混杂、翻页数据重复漂移等问题，导致批量采集漏数据、数据冗余错乱。本文跳出基础参数教学，聚焦&lt;strong&gt;全量数据完整性、分页边界容错、脏数据过滤&lt;/strong&gt;，提供一套生产级稳定采集封装方案。&lt;br/&gt;该接口区别于关键词搜索接口，可精准抓取指定店铺全部商品，支持区分在售、下架商品，但原生接口无自动终止机制，无脑翻页极易造成任务空跑、数据缺失，是开发对接的核心难点。&lt;/p&gt;&lt;p data-pid=&quot;LSy5VtqZ&quot;&gt;&lt;br/&gt;一、核心踩坑痛点梳理&lt;br/&gt;1. 分页硬限制：官方隐性限制最大有效页码100，超出后永久返回空列表，普通循环无法抓取全量商品；2. 数据混杂问题：默认返回包含下架、预售商品，干扰正常业务统计；3. 分页漂移：高频翻页易出现商品重复推送，无去重机制会导致数据冗余。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://pic1.zhimg.com/80/v2-16c78e7f68f8567809db1aba698953a0_720w.jpg&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1177&quot; data-rawheight=&quot;662&quot; data-original-token=&quot;v2-f22fdc1028315814f17e093f6e9ea79e&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1177&quot; data-original=&quot;https://pic1.zhimg.com/v2-16c78e7f68f8567809db1aba698953a0_r.jpg&quot; data-actualsrc=&quot;https://pic1.zhimg.com/v2-16c78e7f68f8567809db1aba698953a0_1440w.jpg&quot; height=&quot;662&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;l3TdJxWn&quot;&gt;&lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;点击获取key和secret&lt;/a&gt;&lt;br/&gt;二、生产级完整封装代码&lt;br/&gt;&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests
import&amp;nbsp;time
import&amp;nbsp;hashlib

class&amp;nbsp;JdShopGoodsSpider:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;app_secret):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.api_url&amp;nbsp;=&amp;nbsp;&amp;quot;https://api.jd.com/routerjson&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.goods_ids&amp;nbsp;=&amp;nbsp;set()&amp;nbsp;#&amp;nbsp;全局去重

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;标准SHA256签名生成
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;build_sign(self,&amp;nbsp;params):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sorted_params&amp;nbsp;=&amp;nbsp;sorted(params.items(),&amp;nbsp;key=lambda&amp;nbsp;x:x[0])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sign_str&amp;nbsp;=&amp;nbsp;self.app_secret&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;quot;.join(f&amp;quot;{k}{v}&amp;quot;&amp;nbsp;for&amp;nbsp;k,v&amp;nbsp;in&amp;nbsp;sorted_params)&amp;nbsp;+&amp;nbsp;self.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.sha256(sign_str.encode()).hexdigest().upper()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;单页商品查询
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;query_shop_page(self,&amp;nbsp;shop_id,&amp;nbsp;page,&amp;nbsp;page_size=20):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timestamp&amp;nbsp;=&amp;nbsp;int(time.time()&amp;nbsp;*&amp;nbsp;1000)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;method&amp;quot;:&amp;nbsp;&amp;quot;jd.union.open.shop.goods.get&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;timestamp&amp;quot;:&amp;nbsp;str(timestamp),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;format&amp;quot;:&amp;nbsp;&amp;quot;json&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;v&amp;quot;:&amp;nbsp;&amp;quot;1.0&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;shopId&amp;quot;:&amp;nbsp;shop_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pageIndex&amp;quot;:&amp;nbsp;page,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pageSize&amp;quot;:&amp;nbsp;min(page_size,&amp;nbsp;20)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params[&amp;quot;sign&amp;quot;]&amp;nbsp;=&amp;nbsp;self.build_sign(params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;=&amp;nbsp;requests.post(self.api_url,&amp;nbsp;data=params,&amp;nbsp;timeout=12)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;res.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;全量商品采集（自动终止+去重）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_shop_all_goods(self,&amp;nbsp;shop_id):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_goods&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;max_limit_page&amp;nbsp;=&amp;nbsp;100&amp;nbsp;#&amp;nbsp;官方最大有效页码
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;page&amp;nbsp;in&amp;nbsp;range(1,&amp;nbsp;max_limit_page&amp;nbsp;+&amp;nbsp;1):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(0.8)&amp;nbsp;#&amp;nbsp;限流适配
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res_data&amp;nbsp;=&amp;nbsp;self.query_shop_page(shop_id,&amp;nbsp;page)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;res_data.get(&amp;quot;jd_union_open_shop_goods_get_response&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;goods_list&amp;nbsp;=&amp;nbsp;resp.get(&amp;quot;data&amp;quot;,&amp;nbsp;[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;goods_list:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&amp;nbsp;#&amp;nbsp;无数据自动终止
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;item&amp;nbsp;in&amp;nbsp;goods_list:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sku_id&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;skuId&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;sku_id&amp;nbsp;or&amp;nbsp;sku_id&amp;nbsp;in&amp;nbsp;self.goods_ids:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.goods_ids.add(sku_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_goods.append({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sku_id&amp;quot;:&amp;nbsp;sku_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;item.get(&amp;quot;skuName&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;price&amp;quot;:&amp;nbsp;item.get(&amp;quot;price&amp;quot;,&amp;nbsp;0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sales&amp;quot;:&amp;nbsp;item.get(&amp;quot;sales&amp;quot;,&amp;nbsp;0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_on_sale&amp;quot;:&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;total&amp;quot;:&amp;nbsp;len(all_goods),&amp;nbsp;&amp;quot;goods_list&amp;quot;:&amp;nbsp;all_goods}

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;JdShopGoodsSpider(&amp;quot;你的APP_KEY&amp;quot;,&amp;nbsp;&amp;quot;你的APP_SECRET&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;client.get_shop_all_goods(&amp;quot;目标店铺ID&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;店铺有效商品总数：&amp;quot;,&amp;nbsp;result[&amp;quot;total&amp;quot;])&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;ctg6wwLB&quot;&gt;&lt;br/&gt;三、差异化核心优化&lt;br/&gt;&lt;strong&gt;1. 分页边界精准控制&lt;/strong&gt;：锁定官方100页最大阈值，避免无效空跑，同时无数据自动break终止循环，提升采集效率。&lt;br/&gt;&lt;strong&gt;2. 双层数据去重&lt;/strong&gt;：通过SKU全局集合去重，彻底解决接口分页漂移导致的商品重复问题，保证数据唯一性。&lt;br/&gt;&lt;strong&gt;3. 限流与容错适配&lt;/strong&gt;：内置请求间隔，适配平台QPS限制，规避429限流报错，同时兼容空数据、异常返回场景。&lt;/p&gt;&lt;p data-pid=&quot;K3_mq9ci&quot;&gt;&lt;br/&gt;四、线上落地总结&lt;br/&gt;京东店铺商品接口最大痛点并非调用逻辑，而是隐性分页限制与数据不稳定问题。本文方案摒弃简单翻页demo，针对性解决漏采、重采、空跑问题，结构化输出纯净在售商品数据。适用于店铺竞品分析、商品盘点、定时巡检等生产场景，稳定性远高于通用基础示例。&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Wed, 19 Aug 2026 17:13:53 +0800</pubDate></item><item><title>微店商品详情接口：私域字段适配与生产级异常自愈方案</title><link>https://apiproxylog.com/?id=220</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;MTgJruFw&quot;&gt;微店作为私域电商核心平台，其商品详情接口与主流公域电商接口差异显著。全网多数教程仅实现基础数据拉取，忽略微店独有特性：价格以分为单位、分销佣金字段动态缺失、图文详情分层嵌套、短时效令牌频繁过期、下架商品返回残缺数据。本文摒弃基础调用演示，聚焦&lt;strong&gt;私域业务适配+数据矫正+异常自愈&lt;/strong&gt;，适配店铺搬家、ERP同步、私域选品等生产场景，提供高稳定性封装方案。&lt;br/&gt;微店开放平台详情接口无冗余字段，但存在大量场景化可选参数，批量同步时极易出现程序报错。核心难点集中在单位转换不统一、非在售商品字段缺失、鉴权令牌有效期短三大痛点，也是线上项目高频崩溃的核心原因。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://picx.zhimg.com/80/v2-d5c4b9382f322512934c2e5c186c7df3_720w.jpg&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1158&quot; data-rawheight=&quot;571&quot; data-original-token=&quot;v2-609e4c1f99d5b2cf200ca4b9dc0556ad&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1158&quot; data-original=&quot;https://picx.zhimg.com/v2-d5c4b9382f322512934c2e5c186c7df3_r.jpg&quot; data-actualsrc=&quot;https://picx.zhimg.com/v2-d5c4b9382f322512934c2e5c186c7df3_1440w.jpg&quot; height=&quot;571&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;tyrhSMao&quot;&gt;&lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;点击获取key和secret&lt;/a&gt;&lt;br/&gt;一、生产级封装代码&lt;br/&gt;代码内置令牌预刷新、价格自动换算、空字段兜底、脏数据过滤，适配长期批量同步任务：&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests
import&amp;nbsp;time

class&amp;nbsp;WeidianItemDetail:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;app_secret):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.api_url&amp;nbsp;=&amp;nbsp;&amp;quot;https://open.weidian.com/api/v1/product/detail&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.access_token&amp;nbsp;=&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.expire_time&amp;nbsp;=&amp;nbsp;0

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;令牌预刷新，解决短时过期问题
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_token(self):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.access_token&amp;nbsp;and&amp;nbsp;time.time()&amp;nbsp;&amp;lt;&amp;nbsp;self.expire_time&amp;nbsp;-&amp;nbsp;100:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.access_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;=&amp;nbsp;requests.post(&amp;quot;https://open.weidian.com/oauth2/token&amp;quot;,&amp;nbsp;data={
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_secret&amp;quot;:&amp;nbsp;self.app_secret,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;grant_type&amp;quot;:&amp;nbsp;&amp;quot;client_credentials&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&amp;nbsp;timeout=12)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data&amp;nbsp;=&amp;nbsp;res.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.access_token&amp;nbsp;=&amp;nbsp;data.get(&amp;quot;access_token&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.expire_time&amp;nbsp;=&amp;nbsp;time.time()&amp;nbsp;+&amp;nbsp;data.get(&amp;quot;expires_in&amp;quot;,&amp;nbsp;7200)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.access_token

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;核心数据归一化矫正
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;parse_detail(self,&amp;nbsp;raw):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;raw.get(&amp;quot;code&amp;quot;)&amp;nbsp;!=&amp;nbsp;0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;status&amp;quot;:&amp;nbsp;0,&amp;nbsp;&amp;quot;msg&amp;quot;:&amp;nbsp;raw.get(&amp;quot;msg&amp;quot;),&amp;nbsp;&amp;quot;data&amp;quot;:&amp;nbsp;None}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item&amp;nbsp;=&amp;nbsp;raw.get(&amp;quot;data&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;分转元，统一价格单位
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;price&amp;nbsp;=&amp;nbsp;round(item.get(&amp;quot;price&amp;quot;,&amp;nbsp;0)&amp;nbsp;/&amp;nbsp;100,&amp;nbsp;2)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;item_id&amp;quot;:&amp;nbsp;item.get(&amp;quot;item_id&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;item.get(&amp;quot;title&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;).strip(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;price_yuan&amp;quot;:&amp;nbsp;price,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;original_price&amp;quot;:&amp;nbsp;round(item.get(&amp;quot;origin_price&amp;quot;,&amp;nbsp;0)/100,&amp;nbsp;2),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;stock&amp;quot;:&amp;nbsp;item.get(&amp;quot;stock_num&amp;quot;,&amp;nbsp;0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sales&amp;quot;:&amp;nbsp;item.get(&amp;quot;sales_num&amp;quot;,&amp;nbsp;0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;commission&amp;quot;:&amp;nbsp;round(item.get(&amp;quot;commission&amp;quot;,0)/100,2),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_on_sale&amp;quot;:&amp;nbsp;item.get(&amp;quot;status&amp;quot;)&amp;nbsp;==&amp;nbsp;1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;main_images&amp;quot;:&amp;nbsp;item.get(&amp;quot;images&amp;quot;,&amp;nbsp;[]),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;detail_content&amp;quot;:&amp;nbsp;item.get(&amp;quot;detail&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;商品详情查询入口
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_item_info(self,&amp;nbsp;item_id):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;headers&amp;nbsp;=&amp;nbsp;{&amp;quot;Authorization&amp;quot;:&amp;nbsp;f&amp;quot;Bearer&amp;nbsp;{self.get_token()}&amp;quot;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;requests.get(f&amp;quot;{self.api_url}?item_id={item_id}&amp;quot;,&amp;nbsp;headers=headers,&amp;nbsp;timeout=15)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.parse_detail(resp.json())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;status&amp;quot;:&amp;nbsp;0,&amp;nbsp;&amp;quot;msg&amp;quot;:&amp;nbsp;f&amp;quot;请求异常：{str(e)}&amp;quot;,&amp;nbsp;&amp;quot;data&amp;quot;:&amp;nbsp;None}

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;WeidianItemDetail(&amp;quot;你的APP_KEY&amp;quot;,&amp;nbsp;&amp;quot;你的APP_SECRET&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(client.get_item_info(&amp;quot;微店商品ID&amp;quot;))&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;youXoqmC&quot;&gt;&lt;br/&gt;二、差异化核心优化点&lt;br/&gt;&lt;strong&gt;1. 单位统一矫正&lt;/strong&gt;：针对微店原生价格、佣金以分为单位的特性，自动转换为元，彻底规避业务统计价格倍率错误。&lt;br/&gt;&lt;strong&gt;2. 令牌自愈机制&lt;/strong&gt;：提前100秒预判令牌过期，批量任务全程无需重启，解决微店2小时短时鉴权失效问题。&lt;br/&gt;&lt;strong&gt;3. 可选字段兼容&lt;/strong&gt;：分销佣金、详情内容等非必返字段全部兜底，避免个别商品字段缺失导致程序中断。&lt;br/&gt;三、线上落地避坑要点&lt;br/&gt;微店接口严格绑定店铺授权，跨店铺查询会返回空数据，调用前需匹配授权店铺ID；接口QPS限制较低，批量采集需增设请求间隔。同时下架商品不会直接报错，仅清空核心字段，代码通过在售状态过滤无效数据，保障业务数据纯净度。&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Tue, 18 Aug 2026 16:35:25 +0800</pubDate></item><item><title>淘宝店铺搜索接口实战：关键词检索店铺列表与业务数据归一化处理</title><link>https://apiproxylog.com/?id=219</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;t3Uqw7Ej&quot;&gt;前言&lt;/p&gt;&lt;p data-pid=&quot;TnO_acx8&quot;&gt;多数公开教程只演示简单调用获取原始店铺
 json 数据，很少关注业务场景下的痛点：同一关键词返回店铺数据字段参差不齐、分页偏移失效、店铺类型混杂（天猫店、淘宝 C 
店、企业店）、部分接口返回冗余嵌套层级深，直接拿到原始数据很难用于数据分析、店铺监控业务。本文从业务落地视角，封装一套具备类型过滤、异常捕获、字段归一化的调用示例，解决直接拿到原始
 JSON 无法直接入库的现实问题。&lt;/p&gt;&lt;p data-pid=&quot;WeyziOW0&quot;&gt;前置准备&lt;/p&gt;&lt;p data-pid=&quot;8x-o2VR_&quot;&gt;调用淘宝开放平台店铺搜索相关接口，需要申请开发者账号，获取
 app_key、app_secret，同时申请对应接口权限。接口核心入参包含搜索关键词、页码、每页条数、店铺筛选条件；需要注意接口存在调用 
QPS 限制，高频场景必须做请求间隔控制，避免触发平台限流返回错误码。&lt;/p&gt;&lt;p data-pid=&quot;quIKtXEb&quot;&gt;很多开发者踩坑点：单纯修改 page 参数无限翻页，当到达最大数据阈值后接口不会返回报错，而是重复返回第一页数据，业务层必须增加逻辑识别该现象。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://picx.zhimg.com/80/v2-0ffefb6b8bd5e018900f497b1399b6f3_720w.webp&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1168&quot; data-rawheight=&quot;658&quot; data-original-token=&quot;v2-ff78792008dbab00c0581edbcf0222ca&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1168&quot; data-original=&quot;https://picx.zhimg.com/v2-0ffefb6b8bd5e018900f497b1399b6f3_r.jpg&quot; data-actualsrc=&quot;https://picx.zhimg.com/v2-0ffefb6b8bd5e018900f497b1399b6f3_1440w.jpg&quot; height=&quot;658&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;i5BQIJ8D&quot;&gt;&lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;点击获取key和secret&lt;/a&gt;&lt;/p&gt;&lt;p data-pid=&quot;KEG6QMZF&quot;&gt;核心 Python 代码示例&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;time
import&amp;nbsp;hashlib
import&amp;nbsp;requests

class&amp;nbsp;TaobaoShopSearch:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;app_secret):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.api_url&amp;nbsp;=&amp;nbsp;&amp;quot;https://gw.api.taobao.com/router/rest&amp;quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;sign_generate(self,&amp;nbsp;params):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sorted_items&amp;nbsp;=&amp;nbsp;sorted(params.items())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw_str&amp;nbsp;=&amp;nbsp;self.app_secret&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;quot;.join([k+str(v)&amp;nbsp;for&amp;nbsp;k,v&amp;nbsp;in&amp;nbsp;sorted_items])&amp;nbsp;+&amp;nbsp;self.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.md5(raw_str.encode(&amp;quot;utf-8&amp;quot;)).hexdigest().upper()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;search_shop_list(self,&amp;nbsp;keyword,&amp;nbsp;page_no=1,&amp;nbsp;page_size=20,&amp;nbsp;shop_type=None):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;method&amp;quot;:&amp;nbsp;&amp;quot;taobao.shop.gets&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;timestamp&amp;quot;:&amp;nbsp;time.strftime(&amp;quot;%Y-%m-%d&amp;nbsp;%H:%M:%S&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;format&amp;quot;:&amp;nbsp;&amp;quot;json&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;v&amp;quot;:&amp;nbsp;&amp;quot;2.0&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;q&amp;quot;:&amp;nbsp;keyword,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;page_no&amp;quot;:&amp;nbsp;page_no,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;page_size&amp;quot;:&amp;nbsp;page_size
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sign&amp;nbsp;=&amp;nbsp;self.sign_generate(params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params[&amp;quot;sign&amp;quot;]&amp;nbsp;=&amp;nbsp;sign
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;requests.get(self.api_url,&amp;nbsp;params=params,&amp;nbsp;timeout=15)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res_json&amp;nbsp;=&amp;nbsp;resp.json()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;接口错误捕获
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;&amp;quot;error_response&amp;quot;&amp;nbsp;in&amp;nbsp;res_json:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;success&amp;quot;:False,&amp;quot;msg&amp;quot;:res_json[&amp;quot;error_response&amp;quot;][&amp;quot;msg&amp;quot;],&amp;quot;data&amp;quot;:[]}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_data&amp;nbsp;=&amp;nbsp;res_json.get(&amp;quot;shop_gets_response&amp;quot;,{}).get(&amp;quot;shops&amp;quot;,{}).get(&amp;quot;shop&amp;quot;,[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result_list&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;shop&amp;nbsp;in&amp;nbsp;shop_data:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;字段归一化，统一输出结构便于入库
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;shop_id&amp;quot;:&amp;nbsp;shop.get(&amp;quot;sid&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;shop_name&amp;quot;:&amp;nbsp;shop.get(&amp;quot;title&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;shop_type&amp;quot;:&amp;nbsp;shop.get(&amp;quot;shop_type&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;seller_nick&amp;quot;:&amp;nbsp;shop.get(&amp;quot;nick&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;credit_score&amp;quot;:&amp;nbsp;shop.get(&amp;quot;shop_credit&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;province&amp;quot;:&amp;nbsp;shop.get(&amp;quot;province&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;city&amp;quot;:&amp;nbsp;shop.get(&amp;quot;city&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;过滤指定店铺类型
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;shop_type&amp;nbsp;and&amp;nbsp;item[&amp;quot;shop_type&amp;quot;]&amp;nbsp;!=&amp;nbsp;shop_type:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result_list.append(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;success&amp;quot;:True,&amp;quot;data&amp;quot;:result_list}

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;TaobaoShopSearch(app_key=&amp;quot;xxx&amp;quot;,&amp;nbsp;app_secret=&amp;quot;xxx&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp_data&amp;nbsp;=&amp;nbsp;client.search_shop_list(keyword=&amp;quot;家居&amp;quot;,page_no=1,page_size=20)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(resp_data)&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;M2hQSp2C&quot;&gt;代码逻辑解析&lt;/p&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;签名函数按照开放平台规则对参数排序生成 MD5 签名，是接口请求合法的关键；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;增加超时、接口错误返回捕获，不会因为单条接口异常直接中断程序；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;对原始嵌套的返回结构做扁平化归一化处理，输出固定字典结构，方便直接写入数据库；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;增加店铺类型过滤预留参数，可以按需筛选天猫、企业店铺、个人 C 店。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p data-pid=&quot;qAtUt5V6&quot;&gt;实际对接踩坑总结&lt;/p&gt;&lt;p class=&quot;ztext-empty-paragraph&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;分页陷阱：接口有最大返回数据上限，页码超过阈值不会报错，数据重复，业务代码要对比前后页数据做去重判断；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;权限管控：店铺搜索接口不是创建账号就自带，需要在开放平台提交接口权限申请，未申请会返回无权限错误；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;QPS 限制，批量采集场景必须加 sleep 间隔，短时间大量请求会被限流；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;部分字段非必返回，不要直接取值，统一使用 get () 方式获取，避免 key 不存在直接抛出程序异常。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Mon, 17 Aug 2026 17:44:50 +0800</pubDate></item><item><title>微店关键词搜索接口：分页黑洞与分销字段归一化实战</title><link>https://apiproxylog.com/?id=218</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;rNSSBC8E&quot;&gt;微店搜索接口和主流电商存在明显差异，除常规商品基础信息外，自带分销佣金、拼团标记等特有业务字段。很多开发只做简单请求，上线后遇到分页穿透、token
 
过期无重试、佣金字段缺失、下架商品混入结果集等问题。本文不从基础参数讲解切入，聚焦生产环境的数据清洗、分页边界处理、自动令牌刷新，适配选品系统、ERP
 商品同步业务场景。&lt;/p&gt;&lt;p data-pid=&quot;9Te1rIy0&quot;&gt;微店开放平台搜索接口采用 OAuth2 鉴权，access_token
 有效期仅 2 
小时，批量任务很容易出现中途鉴权失效。另外接口存在分页黑洞：页码超过平台内部阈值，不会返回报错，只会持续返回空列表，若直接循环页码会造成死循环。同时价格单位为分，不做转换直接入库会出现价格放大
 100 倍的 bug，分销佣金字段仅部分商品返回，直接读取会触发字典异常。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://pic4.zhimg.com/80/v2-9af2a8734cd222eec0fe714ca6299d89_720w.jpg&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1173&quot; data-rawheight=&quot;579&quot; data-original-token=&quot;v2-d42c45497f105098d91739ee0d43d784&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1173&quot; data-original=&quot;https://pic4.zhimg.com/v2-9af2a8734cd222eec0fe714ca6299d89_r.jpg&quot; data-actualsrc=&quot;https://pic4.zhimg.com/v2-9af2a8734cd222eec0fe714ca6299d89_1440w.jpg&quot; height=&quot;579&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;G_jKiFn1&quot;&gt;&lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_blank&quot;&gt;点击获取key和secret&lt;/a&gt;&lt;/p&gt;&lt;p data-pid=&quot;gcxjGu3u&quot;&gt;下面封装类集成 token 自动刷新、分页终止判断、分销字段安全解析、异常重试，过滤已下架商品，输出标准化数据集。&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests
import&amp;nbsp;time
from&amp;nbsp;urllib.parse&amp;nbsp;import&amp;nbsp;quote

class&amp;nbsp;WeidianKeywordSearch:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;app_secret):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.token&amp;nbsp;=&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.token_expire&amp;nbsp;=&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.search_api&amp;nbsp;=&amp;nbsp;&amp;quot;https://open.weidian.com/api/v1/item/search&amp;quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_refresh_token(self):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;自动刷新访问令牌，临近过期主动更新&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.token&amp;nbsp;and&amp;nbsp;time.time()&amp;nbsp;&amp;lt;&amp;nbsp;self.token_expire&amp;nbsp;-&amp;nbsp;120:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;requests.post(&amp;quot;https://open.weidian.com/oauth2/token&amp;quot;,&amp;nbsp;data={
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_secret&amp;quot;:&amp;nbsp;self.app_secret,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;grant_type&amp;quot;:&amp;nbsp;&amp;quot;client_credentials&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&amp;nbsp;timeout=12)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;=&amp;nbsp;resp.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.token&amp;nbsp;=&amp;nbsp;res.get(&amp;quot;access_token&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.token_expire&amp;nbsp;=&amp;nbsp;time.time()&amp;nbsp;+&amp;nbsp;res.get(&amp;quot;expires_in&amp;quot;,&amp;nbsp;7200)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_parse_item(self,&amp;nbsp;raw):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;字段归一化，处理空值、价格单位转换、分销字段兼容&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;item_id&amp;quot;:&amp;nbsp;raw.get(&amp;quot;item_id&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;raw.get(&amp;quot;title&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;).strip(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;price&amp;quot;:&amp;nbsp;round(raw.get(&amp;quot;price&amp;quot;,0)/100,2),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sales&amp;quot;:&amp;nbsp;raw.get(&amp;quot;sales_num&amp;quot;,0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;main_image&amp;quot;:&amp;nbsp;raw.get(&amp;quot;cover_image&amp;quot;,&amp;quot;&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;commission_rate&amp;quot;:&amp;nbsp;raw.get(&amp;quot;commission_rate&amp;quot;,0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_group_buy&amp;quot;:&amp;nbsp;bool(raw.get(&amp;quot;is_group&amp;quot;,0)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;stock&amp;quot;:&amp;nbsp;raw.get(&amp;quot;stock_num&amp;quot;,0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_on_sale&amp;quot;:&amp;nbsp;raw.get(&amp;quot;status&amp;quot;)&amp;nbsp;==&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;search(self,&amp;nbsp;keyword,&amp;nbsp;page=1,&amp;nbsp;page_size=20):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._refresh_token()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;keyword&amp;quot;:&amp;nbsp;quote(keyword),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;page_no&amp;quot;:&amp;nbsp;page,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;page_size&amp;quot;:&amp;nbsp;min(page_size,50)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;headers&amp;nbsp;=&amp;nbsp;{&amp;quot;Authorization&amp;quot;:&amp;nbsp;f&amp;quot;Bearer&amp;nbsp;{self.token}&amp;quot;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r&amp;nbsp;=&amp;nbsp;requests.get(self.search_api,&amp;nbsp;params=params,&amp;nbsp;headers=headers,&amp;nbsp;timeout=15)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;json_data&amp;nbsp;=&amp;nbsp;r.json()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;json_data.get(&amp;quot;code&amp;quot;)&amp;nbsp;!=&amp;nbsp;0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;ok&amp;quot;:False,&amp;quot;msg&amp;quot;:json_data.get(&amp;quot;msg&amp;quot;),&amp;quot;data&amp;quot;:[],&amp;quot;total&amp;quot;:0}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw_list&amp;nbsp;=&amp;nbsp;json_data.get(&amp;quot;data&amp;quot;,{}).get(&amp;quot;items&amp;quot;,[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;json_data.get(&amp;quot;data&amp;quot;,{}).get(&amp;quot;total&amp;quot;,0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;[self._parse_item(i)&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;raw_list&amp;nbsp;if&amp;nbsp;i.get(&amp;quot;status&amp;quot;)==1]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;ok&amp;quot;:True,&amp;quot;msg&amp;quot;:&amp;quot;success&amp;quot;,&amp;quot;data&amp;quot;:result,&amp;quot;total&amp;quot;:total}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;ok&amp;quot;:False,&amp;quot;msg&amp;quot;:str(e),&amp;quot;data&amp;quot;:[],&amp;quot;total&amp;quot;:0}

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;WeidianKeywordSearch(&amp;quot;your_app_key&amp;quot;,&amp;quot;your_app_secret&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output&amp;nbsp;=&amp;nbsp;client.search(&amp;quot;手提包&amp;quot;,page=1,page_size=20)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(output)&lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Sun, 16 Aug 2026 15:22:03 +0800</pubDate></item><item><title>1688商品详情接口：B端阶梯价格解析与结构化容错实战</title><link>https://apiproxylog.com/?id=217</link><description>&lt;p&gt;&lt;span id=&quot;content&quot;&gt;&lt;p data-first-child=&quot;&quot; data-pid=&quot;_IdT5dJa&quot;&gt;1688阿里巴巴商品详情接口与C端电商接口核心差异极大，其主打B端批发模式，存在阶梯价格、起订量限制、混批规则、供应商资质等独有字段。目前多数对接教程仅简单获取原始数据，普遍出现&lt;strong&gt;批发价格解析错乱、起订量字段缺失、空规格报错、下架脏数据残留&lt;/strong&gt;等线上问题。本文跳出基础调用演示，聚焦B端业务特性，实现接口数据标准化清洗与异常容错封装，适配货源采集、供应链比价、商家数据分析场景。&lt;br/&gt;本次对接基于1688开放平台官方详情接口，针对性解决B端核心痛点：多阶梯批发价无法直接读取、SKU规格嵌套不稳定、商品下架后字段残缺、图片鉴权访问异常等高频问题。&lt;/p&gt;&lt;p data-pid=&quot;fYZ_iglk&quot;&gt;&lt;br/&gt;一、B端接口核心对接难点&lt;br/&gt;不同于淘宝、京东C端一口价模式，1688接口核心难点集中三点：一是价格为阶梯区间模式，无固定单价，原始字段杂乱；二是商品支持混批、定制、一件代发多种模式，字段返回结构不统一；三是失效商品不会直接报错，仅返回残缺数据，极易导致程序中断。&lt;/p&gt;&lt;figure data-size=&quot;normal&quot;&gt;&lt;div class=&quot;RichText-ConditionalImagePortal&quot;&gt;&lt;img src=&quot;https://pic3.zhimg.com/80/v2-985f0bd187d5388710dac0bbe4c02e04_720w.jpg&quot; data-caption=&quot;&quot; data-size=&quot;normal&quot; data-rawwidth=&quot;1168&quot; data-rawheight=&quot;575&quot; data-original-token=&quot;v2-f4a3a09b60b5da627bddaf0f8d9ebea2&quot; class=&quot;origin_image zh-lightbox-thumb lazy&quot; width=&quot;1168&quot; data-original=&quot;https://pic3.zhimg.com/v2-985f0bd187d5388710dac0bbe4c02e04_r.jpg&quot; data-actualsrc=&quot;https://pic3.zhimg.com/v2-985f0bd187d5388710dac0bbe4c02e04_1440w.jpg&quot; height=&quot;575&quot; data-lazy-status=&quot;ok&quot;/&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-pid=&quot;qHsWdURE&quot;&gt;&lt;br/&gt;&lt;a href=&quot;https://o0b.cn/iiiace&quot; target=&quot;_self&quot;&gt;点击获取key和secret&lt;/a&gt;&lt;/p&gt;&lt;p data-pid=&quot;a2GP_FXP&quot;&gt;二、生产级完整封装代码&lt;/p&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;import&amp;nbsp;requests
import&amp;nbsp;time

class&amp;nbsp;Ali1688DetailClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key,&amp;nbsp;access_token):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.access_token&amp;nbsp;=&amp;nbsp;access_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.api_url&amp;nbsp;=&amp;nbsp;&amp;quot;https://gw.open.1688.com/openapi/param2/1/com.alibaba.offer.get&amp;quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;核心：B端数据归一化清洗，适配阶梯价格与空字段
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;parse_offer_data(self,&amp;nbsp;raw_data):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;raw_data&amp;nbsp;or&amp;nbsp;raw_data.get(&amp;quot;error_code&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;status&amp;quot;:0,&amp;nbsp;&amp;quot;msg&amp;quot;:&amp;quot;商品失效或权限异常&amp;quot;,&amp;nbsp;&amp;quot;data&amp;quot;:None}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item&amp;nbsp;=&amp;nbsp;raw_data.get(&amp;quot;result&amp;quot;,&amp;nbsp;{})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;解析B端阶梯批发价
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;price_range&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;priceRanges&amp;quot;,&amp;nbsp;[])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;price_list&amp;nbsp;=&amp;nbsp;[{&amp;quot;min_num&amp;quot;:p.get(&amp;quot;startQuantity&amp;quot;),&amp;quot;price&amp;quot;:p.get(&amp;quot;price&amp;quot;)}&amp;nbsp;for&amp;nbsp;p&amp;nbsp;in&amp;nbsp;price_range]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;标准化结构化数据
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;offer_id&amp;quot;:&amp;nbsp;item.get(&amp;quot;offerId&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;item.get(&amp;quot;subject&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;).strip(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;min_order&amp;quot;:&amp;nbsp;item.get(&amp;quot;minOrderQuantity&amp;quot;,&amp;nbsp;0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;price_rule&amp;quot;:&amp;nbsp;price_list,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;supplier&amp;quot;:&amp;nbsp;item.get(&amp;quot;supplier&amp;quot;,&amp;nbsp;{}).get(&amp;quot;companyName&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_one_piece&amp;quot;:&amp;nbsp;item.get(&amp;quot;supportOnePiece&amp;quot;,&amp;nbsp;False),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;main_imgs&amp;quot;:&amp;nbsp;item.get(&amp;quot;imageList&amp;quot;,&amp;nbsp;[]),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;is_valid&amp;quot;:&amp;nbsp;item.get(&amp;quot;isValid&amp;quot;,&amp;nbsp;False)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;status&amp;quot;:1,&amp;nbsp;&amp;quot;msg&amp;quot;:&amp;quot;success&amp;quot;,&amp;nbsp;&amp;quot;data&amp;quot;:res}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_offer_detail(self,&amp;nbsp;offer_id):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;access_token&amp;quot;:&amp;nbsp;self.access_token,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;offerId&amp;quot;:&amp;nbsp;offer_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;timestamp&amp;quot;:&amp;nbsp;int(time.time()*1000)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;requests.get(self.api_url,&amp;nbsp;params=params,&amp;nbsp;timeout=15)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.parse_offer_data(resp.json())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;status&amp;quot;:0,&amp;nbsp;&amp;quot;msg&amp;quot;:f&amp;quot;请求异常：{str(e)}&amp;quot;,&amp;nbsp;&amp;quot;data&amp;quot;:None}

#&amp;nbsp;调用示例
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;Ali1688DetailClient(&amp;quot;你的APP_KEY&amp;quot;,&amp;nbsp;&amp;quot;你的ACCESS_TOKEN&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;client.get_offer_detail(&amp;quot;1688商品ID&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(result)&lt;/pre&gt;&lt;/div&gt;&lt;p data-pid=&quot;Li-TudX8&quot;&gt;&lt;br/&gt;三、差异化核心优化点&lt;br/&gt;&lt;strong&gt;1. 阶梯价格专项解析&lt;/strong&gt;：专门适配1688独有批量定价规则，拆解起订数量、对应单价，解决B端价格数据错乱问题，满足批发比价业务需求。&lt;br/&gt;&lt;strong&gt;2. 全维度容错机制&lt;/strong&gt;：对下架、失效、权限不足的商品做统一拦截，兼容空数组、空字段场景，彻底避免KeyError程序崩溃。&lt;br/&gt;&lt;strong&gt;3. 业务字段精简重构&lt;/strong&gt;：过滤冗余营销字段，保留起订量、一件代发、批发价等B端核心字段，适配供应链业务场景，减少数据存储压力。&lt;/p&gt;&lt;p data-pid=&quot;2Esghx2f&quot;&gt;&lt;br/&gt;四、线上落地避坑总结&lt;br/&gt;1688接口权限管控严格，未开通对应权限会返回空数据；批量采集需控制QPS，避免高频请求触发限流。同时平台部分商品图片需登录鉴权访问，批量抓取图片时需单独适配。此外，定制类商品无固定阶梯价格，业务端需单独做特殊逻辑处理。&lt;br/&gt;本文方案摒弃基础请求演示，完全围绕B端供应链业务优化，解决原生接口结构不稳定、价格体系复杂的核心痛点，可直接用于线上稳定部署。&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;</description><pubDate>Fri, 14 Aug 2026 17:03:44 +0800</pubDate></item></channel></rss>