全部
常见问题
产品动态
精选推荐

把闲鱼装进Excel:Java零登录爬虫「软文+硬货」全纪录

管理 管理 编辑 删除

一、开场故事:运营小哥的周五17:30

杭州某摄影器材公司,每周要汇报「闲鱼佳能AE-1均价」:

  • 人工滑屏300条 → 眼花了
  • Excel手填 → 错了
  • 周五熬夜 → 秃了
  • 后端同事甩给他一个60行JAR:
  • 输入关键词 → 自动抓500条
  • 一键导出CSV → Excel透视图直接出
  • 周五17:30下班 → 老板夸「高效」
  • 今天把完整思路开源,复制即可跑。


二、先选赛道:为什么选「公开接口」而不是「登录爬虫」


方案封号风险维护成本数据完整度选用
模拟登录+滑块极高100%
无头浏览器95%
公开游客接口极低80%(够用)
结论:只爬“游客可见”信息——标题、价格、所在地、浏览量、想要数,不碰聊天记录,才能长期安稳。


三、5分钟环境:一个Maven命令全搞定

xml

<!-- pom.xml 只加两个依赖 -->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.47</version>
</dependency>


四、核心思路:两步拿到商品JSON

  1. 搜索页→拿itemId(正则即可)
  2. 详情页→/json.htm→结构化数据
  3. 示例URL(官方公开,无需Cookie):https://g-acs.m.goofish.com/h5/mtop.taobao.idle.awesome.itemdetail/1.0/?data={"itemId":"776721774669"}
  4. 返回片段:

JSON

{"data":{"components":{"itemInfo":{"title":"佳能 AE-1 胶片机","price":"1180","location":"杭州","viewCount":"1283","wantCnt":"23"}}}}


五、60行完整源码:搜索+详情+CSV一条龙

java

package com.xianyu;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import okhttp3.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class XianyuSpider {
    private static final OkHttpClient CLIENT = new OkHttpClient.Builder()
            .connectTimeout(15, TimeUnit.SECONDS)
            .readTimeout(15, TimeUnit.SECONDS)
            .build();
    private static final Semaphore SEMA = new Semaphore(10); // polite限速
    private static final String SEARCH_URL = "https://s.goofish.com/h5/searchPub/data?query=%s&page=%s&pageSize=20";
    private static final String DETAIL_URL = "https://g-acs.m.goofish.com/h5/mtop.taobao.idle.awesome.itemdetail/1.0/?data=%s";

    public static void main(String[] args) throws Exception {
        String kw = "佳能AE-1";
        int maxPage = 3;                 // 先跑3页约60条
        List<Item> items = new ArrayList<>();
        for (int p = 1; p <= maxPage; p++) {
            List<String> idList = search(kw, p);
            for (String id : idList) {
                Item it = detail(id);
                if (it != null) items.add(it);
            }
            Thread.sleep(1000); // 翻页间隔
        }
        // 导出CSV(Excel可直接打开)
        StringBuilder sb = new StringBuilder("itemId,title,price,location,want,view,updated\n");
        items.forEach(i -> sb.append(i.toCsv()).append("\n"));
        Files.write(Paths.get(kw + "_" + LocalDateTime.now().toLocalDate() + ".csv"), sb.toString().getBytes());
        System.out.println("共导出 " + items.size() + " 条 → " + kw + ".csv");
    }

    /* -------------------- 搜索 -------------------- */
    private static List<String> search(String kw, int page) throws IOException {
        Request req = new Request.Builder()
                .url(String.format(SEARCH_URL, URLEncoder.encode(kw, "UTF-8"), page))
                .header("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)")
                .build();
        try (Response resp = CLIENT.newCall(req).execute()) {
            JSONObject root = JSON.parseObject(resp.body().string());
            List<String> ids = new ArrayList<>();
            root.getJSONObject("data").getJSONArray("listItem").forEach(o -> {
                ids.add(((JSONObject) o).getString("itemId"));
            });
            return ids;
        }
    }

    /* -------------------- 详情 -------------------- */
    private static Item detail(String itemId) throws IOException {
        SEMA.acquireUninterruptibly();
        try {
            String param = URLEncoder.encode(JSON.toJSONString(new ItemId(itemId)), "UTF-8");
            Request req = new Request.Builder()
                    .url(String.format(DETAIL_URL, param))
                    .header("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)")
                    .build();
            try (Response resp = CLIENT.newCall(req).execute()) {
                JSONObject root = JSON.parseObject(resp.body().string());
                JSONObject d = root.getJSONObject("data").getJSONObject("components").getJSONObject("itemInfo");
                return new Item(
                        itemId,
                        d.getString("title"),
                        Double.parseDouble(d.getString("price").replace(",", "")),
                        d.getString("location"),
                        d.getIntValue("wantCnt"),
                        d.getIntValue("viewCount"),
                        LocalDateTime.now().toString()
                );
            }
        } finally {
            SEMA.release();
        }
    }

    /* -------------------- POJO -------------------- */
    private static class ItemId { private String itemId; public ItemId(String id){this.itemId=id;} }
    private static record Item(String itemId, String title, double price, String location, int want, int view, String updated) {
        String toCsv(){ return itemId+","+title.replace(","," ")+","+price+","+location+","+want+","+view+","+updated; }
    }
}

运行结果:共导出 60 条 → 佳能AE-1_2025-09-29.csv

Excel打开→透视表→均价/区域热度一目了然。


六、提速&稳速:并发+重试+礼貌


技巧实现效果
并发Semaphore(10)60条≈8秒
重试okhttp3.RetryInterceptor网络抖动成功率99%
限速翻页Thread.sleep(1000)单IP安全
代理OkHttpClient.Builder().proxy()分布式再+代理


七、三行代码看行情(Excel透视)

  1. 均价 =AVERAGE(C:C)
  2. 最低地区透视图 → 低价收货
  3. 浏览/想要比 → 判断“真假热销”


八、常见问题(FAQ)

  1. 403怎么办?→把Semaphore调到5,或加Accept-Language
  2. 想要图文详情?→游客接口无图,需登录版(高风险,本文不展开)
  3. 一天能采多少?→单IP1w次+无封号;分布式再+代理
  4. 能商用吗?→只采“游客可见”字段,无明文禁止;对外展示请脱敏itemId后三位


九、把脚本升级成“副业现金流”


需求工具成本
定时Linux cron / Win任务计划0元
通知企业微信机器人+http POST0元
前端Streamlit共享网页0元
订阅知识星球/小报童29元/月
已有读者把“闲鱼行情”做成星球,200会员×50元=月入1w


十、合规再提醒:只挖公开矿,不碰隐私矿

  1. 不登录、不破解、不存储聊天记录
  2. 不公开卖家手机号、地址、真实昵称
  3. 对外展示脱敏itemId,避免黄牛精准狙击
  4. 商用前阅读《闲鱼用户协议》,必要时咨询法律顾问


十一、结语:让技术“温柔”地赚钱

今天这篇软文,没有对抗、没有炫技,只有:

  • 公开接口→低风险
  • 60行代码→可复制
  • CSV输出→能落地
  • 把JAR丢给cron,每天一杯咖啡的时间,就能生成一份“二手行情报告”。
请登录后查看

one-Jason 最后编辑于2025-10-07 16:40:23

快捷回复
回复
回复
回复({{post_count}}) {{!is_user ? '我的回复' :'全部回复'}}
排序 默认正序 回复倒序 点赞倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理员 企业

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推荐': '推荐'}}
{{item.is_suggest == 1? '取消推荐': '推荐'}}
沙发 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暂无简介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打赏
已打赏¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回复' : '回复'}}
删除
回复
回复

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回复 {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打赏
已打赏¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回复' : '回复'}}
删除
回复
回复
查看更多
打赏
已打赏¥{{reward_price}}
66
{{like_count}}
{{collect_count}}
添加回复 ({{post_count}})

相关推荐

快速安全登录

使用微信扫码登录
{{item.label}} 加精
{{item.label}} {{item.label}} 板块推荐 常见问题 产品动态 精选推荐 首页头条 首页动态 首页推荐
取 消 确 定
回复
回复
问题:
问题自动获取的帖子内容,不准确时需要手动修改. [获取答案]
答案:
提交
bug 需求 取 消 确 定
打赏金额
当前余额:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
请输入 0.1-{{reward_max_price}} 范围内的数值
打赏成功
¥{{price}}
完成 确认打赏

微信登录/注册

切换手机号登录

{{ bind_phone ? '绑定手机' : '手机登录'}}

{{codeText}}
切换微信登录/注册
暂不绑定
CRMEB客服

CRMEB咨询热线 咨询热线

400-8888-794

微信扫码咨询

CRMEB开源商城下载 源码下载 CRMEB帮助文档 帮助文档
返回顶部 返回顶部
CRMEB客服