Java爬虫1688详情api接口实战解析

下面给出一份可直接落地的「Java 版 1688 商品详情 API 爬虫」完整示例,覆盖签名算法、HTTP 调用、JSON 解析、异常重试、频率控制等关键要点,复制即可运行。

(注:1688 接口需企业认证并申请 AppKey / AppSecret,以下代码以官方 REST 网关 item_get 为例,也可平替为第三方代理网关,只需换域名即可 。)


一、Maven 依赖

XML 复制代码
<dependencies>
    <!-- HTTP -->
    <dependency>
        <groupId>org.apache.httpcomponents.client5</groupId>
        <artifactId>httpclient5</artifactId>
        <version>5.3.1</version>
    </dependency>
    <!-- JSON -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.17.0</version>
    </dependency>
</dependencies>

二、签名工具(1688 官方 MD5 签名规则)

java 复制代码
public class SignUtil {
    public static String sign(TreeMap<String, String> params, String appSecret) {
        StringBuilder sb = new StringBuilder(appSecret);
        for (Map.Entry<String, String> e : params.entrySet()) {
            sb.append(e.getKey()).append(e.getValue());
        }
        sb.append(appSecret);
        return md5(sb.toString()).toUpperCase();
    }

    private static String md5(String raw) {
        try {
            byte[] bs = MessageDigest.getInstance("MD5").digest(raw.getBytes(StandardCharsets.UTF_8));
            StringBuilder hex = new StringBuilder();
            for (byte b : bs) hex.append(String.format("%02X", b & 0xFF));
            return hex.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

三、统一入口 ------ ItemGetService

java 复制代码
public class ItemGetService {
    private static final String GATEWAY = "https://api.1688.com/router/rest";
    private final String appKey;
    private final String appSecret;
    private final CloseableHttpClient http;

    public ItemGetService(String appKey, String appSecret) {
        this.appKey = appKey;
        this.appSecret = appSecret;
        this.http = HttpClients.custom()
                               .setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
                                   .setMaxConnTotal(50).setMaxConnPerRoute(10).build())
                               .build();
    }

    /** 获取商品详情(自动重试 3 次) */
    public ItemDO getItem(long numIid) throws IOException {
        TreeMap<String, String> params = new TreeMap<>();
        params.put("method", "item_get");
        params.put("app_key", appKey);
        params.put("timestamp", String.valueOf(System.currentTimeMillis()));
        params.put("num_iid", String.valueOf(numIid));
        params.put("v", "2.0");
        params.put("sign_method", "md5");
        params.put("format", "json");
        params.put("sign", SignUtil.sign(params, appSecret));

        String url = GATEWAY + "?" + URLEncodedUtils.format(
                params.entrySet().stream()
                      .map(e -> new BasicNameValuePair(e.getKey(), e.getValue()))
                      .collect(Collectors.toList()), StandardCharsets.UTF_8);

        for (int i = 0; i < 3; i++) {
            try (CloseableHttpResponse resp = http.execute(new HttpGet(url))) {
                if (resp.getCode() == 200) {
                    JsonNode root = new ObjectMapper().readTree(EntityUtils.toString(resp.getEntity()));
                    if ("0".equals(root.get("code").asText())) {
                        return new ObjectMapper().convertValue(root.get("item"), ItemDO.class);
                    }
                    throw new IllegalStateException("API 业务错误: " + root.get("msg").asText());
                }
            } catch (Exception e) {
                if (i == 2) throw e;
                try { Thread.sleep(1000); } catch (InterruptedException ignore) {}
            }
        }
        throw new RuntimeException("重试 3 次仍失败");
    }

    @Data  // lombok
    public static class ItemDO {
        private String title;
        private BigDecimal price;
        private Integer num;          // 库存
        private String picUrl;
        private List<Sku> skus;
    }

    public void shutdown() throws IOException {
        http.close();
    }
}

四、频率控制 + 批量调用示例

java 复制代码
public class CrawlerBoot {
    public static void main(String[] args) throws Exception {
        ItemGetService api = new ItemGetService("你的AppKey", "你的AppSecret");

        List<Long> numIids = List.of(610947572360L, 623456789012L); // 商品ID池
        for (Long id : numIids) {
            ItemGetService.ItemDO item = api.getItem(id);
            System.out.printf("标题=%s 价格=%s 库存=%d%n",
                    item.getTitle(), item.getPrice(), item.getNum());
            Thread.sleep(350);          // 约 3 次/秒,低于官方 5 次/秒限制
        }
        api.shutdown();
    }
}

五、常见坑 & 优化建议

  1. 签名顺序必须 TreeMap 升序,否则 4005 授权失败。

  2. 免费账号每日调用上限 1 万次,超出需购买套餐;峰值时段做好限流与重试。

  3. 如需 SKU 图、阶梯价、近 30 天销量,需在参数额外指定 fields=skus,priceRange,saleInfo。

  4. 若走第三方代理网关(如 api-gw.onebound.cn),签名规则不变,仅换域名即可。

  5. 数据落库时建议用 ON DUPLICATE KEY UPDATE 做幂等,避免重复写入。


六、一句话总结

以上代码即为"Java 爬虫 1688 详情 API 接口"的最小可运行骨架,已帮你屏蔽掉签名、编码、重试、频率等所有细节,直接填上自己的 AppKey / Secret 即可把 1688 商品库变成本地数据表

相关推荐
Escalating_xu24 分钟前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络
程序猿乐锅1 小时前
万字详解Single-flight(单飞模式)
java·开发语言·分布式·后端·学习·single-flight
Java后端的Ai之路1 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
AntsData1 小时前
用 12K+ 条亚马逊评论信号,定位机械键盘下一版该改什么
java·大数据·计算机外设
code2cat2 小时前
【随笔】连续批处理:长短请求怎样在迭代之间补位
java·人工智能·后端·大语言模型·vllm
最强小杰2 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
Flynn Liang2 小时前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
灿飞2 小时前
Kotlin与Java虚拟机六:基础与类型系统:一切皆对象,但对象有代价
java·kotlin
计算机毕设定制辅导-无忧学长2 小时前
《基于微信小程序健康习惯激励系统设计与实现》
java·spring boot·mysql·微信小程序·uniapp·健康习惯激励系统
揽星河..2 小时前
【C语言】指针
c语言·开发语言