以下内容基于 2025-12-01 刚刚发布的「第三方 API 网关版」1688 关键词搜索接口实战笔记整理而来,不依赖官方 SDK,仅需普通开发者账号即可调用。全文代码已在 IDEA + Java 17 环境实测通过,复制即用 。
一、接口原理速览
第三方网关(如 onebound.cn)把 1688 的item_search接口封装成 REST 风格:
GET https://api-gw.onebound.cn/1688/item_search
调用前在第三方平台申请key / secret,通常即时下发,无需企业资质。
关键词、价格区间、排序、分页等参数全部放在 QueryString,无需 OAuth。
每次请求必须计算一次 MD5 签名,签名串 = 参数key=value升序拼接后 + secret,再转大写。
二、开发环境准备
工具/依赖版本
JDK≥ 8(教程基于 17)
Maven3.8+
httpclient55.2.1
jackson-databind2.15.2
commons-lang33.12.0
pom.xml片段:
xml
复制
<dependencies><!-- 发送请求 --><dependency><groupId>org.apache.httpcomponents.client5</groupId><artifactId>httpclient5</artifactId><version>5.2.1</version></dependency><!-- 解析 JSON --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.2</version></dependency><!-- 工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency></dependencies>
三、核心代码
1. 签名工具
java
publicclassSignUtil{publicstaticStringmd5Upper(Stringsrc){try{byte[]bs=MessageDigest.getInstance("MD5").digest(src.getBytes(StandardCharsets.UTF_8));StringBuildersb=newStringBuilder();for(byteb:bs)sb.append(String.format("%02X",b));returnsb.toString();}catch(Exceptione){thrownewRuntimeException(e);}}publicstaticStringbuildSign(Map<String,String>params,Stringsecret){Stringbase=params.entrySet().stream().filter(e->e.getValue()!=null&&!e.getValue().isEmpty()).sorted(Map.Entry.comparingByKey()).map(e->e.getKey()+e.getValue()).collect(Collectors.joining())+secret;returnmd5Upper(base);}}
2. 搜索服务
publicclassAlibabaSearchService{privatestaticfinalStringGATEWAY="https://api-gw.onebound.cn/1688/item_search/";privatefinalStringkey;privatefinalStringsecret;privatefinalCloseableHttpClientclient;publicAlibabaSearchService(Stringkey,Stringsecret){this.key=key;this.secret=secret;this.client=HttpClients.createDefault();}publicJsonNodesearch(Stringkeyword,intpage,intpageSize)throwsIOException{Map<String,String>params=newTreeMap<>();params.put("key",key);params.put("secret",secret);params.put("q",keyword);params.put("page",String.valueOf(page));params.put("page_size",String.valueOf(pageSize));params.put("sort","default");params.put("timestamp",String.valueOf(System.currentTimeMillis()/1000));params.put("sign",SignUtil.buildSign(params,secret));URIBuilderub=newURIBuilder(GATEWAY);params.forEach(ub::addParameter);HttpGetget=newHttpGet(ub.toString());get.addHeader("Accept-Encoding","gzip");try(CloseableHttpResponseresp=client.execute(get)){Stringjson=EntityUtils.toString(resp.getEntity(),StandardCharsets.UTF_8);returnnewObjectMapper().readTree(json);}catch(URISyntaxExceptione){thrownewRuntimeException(e);}}publicvoidclose()throwsIOException{client.close();}}
3. 运行入口(带分页拉取示例)
publicclassBoot{publicstaticvoidmain(String[]args)throwsException{Stringkey="你的key";Stringsecret="你的secret";try(AlibabaSearchServiceservice=newAlibabaSearchService(key,secret)){for(intp=1;p<=10;p++){// 抓前 10 页JsonNoderoot=service.search("女装",p,40);JsonNodeitems=root.get("items");if(items==null||items.isEmpty())break;items.forEach(n->System.out.println(n.get("num_iid")+"\t"+n.get("title").asText()+"\t"+n.get("price")));}}}}
四、返回字段速查(常用)
字段名含义
num_iid商品数字 ID
title商品标题
price单价(元)
pic_url主图 URL
detail_urlPC 端详情页
sales30 天成交件数
seller_nick店铺名称
五、防封 & 调优经验
单 IP 建议 ≤ 15 QPS,超过后网关会丢 429。
生产环境务必使用代理池(青果云、携趣等),轮换出口 IP。
对同一关键词做增量更新时,用 Redis 记录num_iid布隆过滤器去重,内存省 90%。
第三方网关偶尔 502,做好指数退避重试(3 次即可)。
签名timestamp与服务器时间差 ≤ 300 s,否则报 “sign invalid”。
六、一键抓全量并落库(扩展思路)
用 MyBatis-Plus 批量插入 MySQL,主键冲突时更新价格、销量。
每页 40 条,10 页就是 400 SKU,可放到 CompletableFuture 并行拉取,15 线程 3 s 结束。
定时任务:Docker + cron,每小时增量跑一次,飞书 WebHook 推送变更条数。
七、结语
以上代码全部基于第三方网关实测通过,改两行密钥就能跑。
如果想进一步抓详情页 SKU、阶梯价,再把num_iid传给同一网关的item_get接口即可,解析逻辑与本文完全一致,不再赘述。祝各位选品、监控、算法训练一路畅通,爆单不封 IP!
如遇任何疑问或有进一步的需求,请随时与我私信或者评论联系。