Skip to main content

xianyu-goofish-cli

ci

极简的闲鱼(Goofish)只读 CLI:扫码登录 → 搜索商品 → 会话列表 → IM 实时流。

许可证 Apache-2.0。仓库:https://git.weisanju.fun/weisanju/xianyu-cli。

实现上刻意避开了两件最麻烦的事:

  1. 不自己复刻 mtop 签名/风控:搜索时用 Patchright 打开真实 Chrome,监听页面自己发出的 mtop.taobao.idlemtopsearch.pc.search 响应,直接解析 JSON。
  2. 不逆向 IM 私有二进制:闲鱼 WebSocket 实际是 LWP(JSON)协议,wss://wss-goofish.dingtalk.com/, 本 CLI 只做注册、心跳、ack 和解码。

本项目是非官方实现,仅用于个人学习与低频只读场景。请遵守闲鱼用户协议;账号风控、封号等后果自负。

安装

pip install xianyu-goofish-cli
patchright install chrome     # 或直接使用系统 Chrome(channel="chrome")

从源码:

git clone https://git.weisanju.fun/weisanju/xianyu-cli.git
cd xianyu-cli
python -m venv .venv
source .venv/bin/activate
pip install -e .

需要本机有 Chrome/Chromium。

Linux 下有头模式默认优先走 Xvfb(等价于内置 xvfb-run 思路),以减少图形环境依赖。 CLI 会对异常终端尺寸环境变量(如 COLUMNS=131072)做清洗,减少“屏幕尺寸不真实”类提示对登录流程的干扰。

从本版本起,CLI 全部通过内置 server 调用:

  • 默认 server 地址:http://127.0.0.1:17357
  • 若本地 server 不存在,CLI 会自动拉起并复用
  • 启动时会检查本地 server /health 返回的 version,若与当前 CLI 版本不一致会自动重启本地 server
  • 也可通过 --server / XIANYU_SERVER 指向远程 server

使用

# 扫码登录:默认有头 Chrome 打开登录页,终端会在拿到二维码后立即渲染,PNG 存在 ~/.xianyu-cli/qr.png
# 若已有有效登录态会直接复用并跳过扫码;Linux 默认优先启用 Xvfb 有头模式
xianyu login

# 显式启动 server(可用于远程部署)
xianyu serve --host 127.0.0.1 --port 17357

# 强制重新扫码(忽略已缓存登录态)
xianyu login --force

# 关闭终端二维码渲染
xianyu login --no-render-qr

# 调小终端二维码(例如 28;仅图片渲染 fallback 时生效)
xianyu login --qr-width 28

# 机器可读:返回登录结果 + 二维码路径(尽力附带 png_base64)
xianyu login --json

# 检查登录态
xianyu whoami

# 搜索(默认无头;若命中风控会自动重试一次 --no-headless)
xianyu search "iPad Pro" --limit 10
xianyu search "相机" --pages 2 --json

# 筛选:价格区间 / 包邮 / 排除关键词 / 有原价(划线价)/ 排序
xianyu search "iPad Pro" --price-min 1000 --price-max 3500 --shipping free
xianyu search "相机" --exclude 配件 --sort price_asc --limit 20
xianyu search "显卡" --has-original-price --sort price_desc

# 指向远程 server
xianyu --server http://10.0.0.8:17357 search "相机" --limit 10

# 会话列表(支持区分私聊/非私聊;可按 cid 过滤)
xianyu chats --limit 50
xianyu chats --private --limit 50
xianyu chats --non-private --limit 50
xianyu chats --cid 1234567890
xianyu chats --json

# 实时监听私信 60 秒(可只看某个 cid)
xianyu watch --seconds 60
xianyu watch --seconds 60 --cid 1234567890
xianyu watch --seconds 60 --json

# 检查更新(只报告)/ 执行升级(pip 安装到当前解释器环境)
xianyu update --check
xianyu update --yes

# 给 AI agent 的用法说明:终端打印 SKILL.md
xianyu skill
xianyu skill --install                    # 写入 ~/.xianyu-cli/skills/xianyu/SKILL.md
xianyu skill --install ~/.claude/skills/xianyu   # 写入指定目录的 SKILL.md

全局 --json 可用于所有命令。全局 --server 可切换到远程 server。

login --json 成功时会返回:

{
  "logged_in": true,
  "cookies": 12,
  "qr": {
    "path": "/home/you/.xianyu-cli/qr.png",
    "png_base64": "iVBORw0KGgoAAA..."
  }
}

其中 png_base64 为尽力返回(读取失败时可能不存在)。 CLI 默认优先用 Python 库 segno 根据二维码原文重渲染终端码(更易扫);若失败则回退 qrencode,最后回退到图片像素渲染。 login --json 时二维码渲染和提示信息会输出到 stderr,stdout 保持纯 JSON。

命令与退出码

命令 说明
login [--timeout N] [--no-headless] [--no-render-qr] [--qr-width N] [--force] 扫码登录,保存 cookie + storage_state;默认优先复用有效登录态并跳过扫码,渲染时优先用 segno;--json 时返回二维码信息
whoami 调用 loginuser.get 验证登录态
search <query> [--limit] [--pages] [--price-min] [--price-max] [--shipping any|free|no] [--exclude WORD] [--has-original-price] [--sort default|price_asc|price_desc] [--no-headless] 拦截搜索响应并解析;筛选在 server 端对已抓取结果进行(先筛选再截断到 --limit)
`chats [--limit] [--private --non-private] [--cid]`
watch [--seconds] [--cid] IM WebSocket 实时事件,可只监听指定会话 CID
update [--check] [--yes] 读取 PyPI 上 xianyu-goofish-cli 的最新版本;默认只报告升级命令,--yes 才用当前 Python 执行 pip install --upgrade
skill [--install [DIR]] 打印给 AI agent 的用法说明(SKILL.md);--install [DIR] 写入 DIR/SKILL.md(默认 ~/.xianyu-cli/skills/xianyu/)
serve [--host] [--port] 启动 RPC server(CLI 默认会自动拉起本地 server)

退出码:0 成功,1 普通错误,2 未登录/登录失效,3 风控拦截,130 Ctrl-C。

数据位置

~/.xianyu-cli/
  cookies.json      # 登录 cookie(0600)
  profile/          # 扫码登录用的 Chrome profile
  storage_state.json
  qr.png            # 最近一次登录二维码
  device.json       # IM 设备 ID(按账号固定)
  im_token.json     # IM accessToken 缓存(30 分钟)

可用 XIANYU_HOME 改根目录。

发布(维护者)

PyPI 分发包名是 xianyu-goofish-cli(xianyu-cli 已被占用),导入包仍为 xianyu_cli,命令为 xianyu。

  1. 仓库 Settings → Actions → Secrets 添加 PYPI_API_TOKEN(PyPI API token,scope 建议只限本项目)。
  2. 改 pyproject.toml 里的 version,提交后打同名 tag:
git tag v0.1.0
git push origin v0.1.0

.forgejo/workflows/release.yml 会校验 tag 与版本一致、构建 sdist/wheel、跑 twine check,再上传 PyPI。 本地手动发布等价命令:

python -m pip install --upgrade build twine
python -m build
TWINE_USERNAME=__token__ TWINE_PASSWORD=pypi-... python -m twine upload dist/*

已知限制

  • 只读:v1 不提供发消息、发布、自动回复。
  • search 依赖页面实际发出搜索请求;未登录/登录失效时页面会弹登录框,CLI 会报“未捕获到搜索响应”。
  • 二维码 canvas 被中心 logo 跨域污染,不能 toDataURL(),本实现用元素截图。
  • 会话列表来自 session.sync,可能与 App 端不完全一致。
  • IM 协议随时可能变化;watch 目前只处理文本/图片/已读/新消息通知。
  • 高频请求会触发 RGV587,CLI 会直接报错退出,不做自动重试风暴。

参考与致谢

协议常量与解析思路参考了以下 Apache-2.0 / MIT 项目:

本项目为独立实现,未复制上述项目的完整代码;详见 NOTICE。

Metadata

Release files for xianyu-goofish-cli 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xianyu-goofish-cli 0.2.0
File Size Uploaded Provenance Actions
xianyu_goofish_cli-0.2.0.tar.gz 44.0 kB Without provenance Details for xianyu_goofish_cli-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for xianyu-goofish-cli 0.2.0
File Interpreter ABI Platform Actions
xianyu_goofish_cli-0.2.0-py3-none-any.whl Python 3 none any Details for xianyu_goofish_cli-0.2.0-py3-none-any.whl

Total release size: 86.9 kB

Release files / xianyu_goofish_cli-0.2.0.tar.gz

Download URL xianyu_goofish_cli-0.2.0.tar.gz
Size 44.0 kB
Tags Source
SHA-256 checksum
How to use checksums
29cf1619ea8edbf9df34d4760d64a1b3bedbe1574e85fe181316123854f4290c
BLAKE2b-256 checksum
How to use checksums
13b00b3c54a0bf67a65d8111be094c89bc71ea36875b0987275d6637e781c102
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / xianyu_goofish_cli-0.2.0-py3-none-any.whl

Download URL xianyu_goofish_cli-0.2.0-py3-none-any.whl
Size 42.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
355f4dd3b315ceae66b38c79ff0935298cba30309e99166dbaa50dbc0035115e
BLAKE2b-256 checksum
How to use checksums
07d180fa359277f2d633da4c576ba413f1ab3036d0f57dd01a54108ede12d09b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for xianyu-goofish-cli 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page