Token导航 LogoToken导航

Agent Skill · 研究检索

xhs-download(xhs 下载)

xhs-download 用于查找、检索和筛选相关信息,适合在 OpenClaw 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

xhs-download 是研究检索类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为执行命令;许可证为 MIT-0,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 35,670。

总安装 2,046周安装 87GitHub Stars 公开资料未说明下载 717核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
2.1.0

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:xhs-download(xhs 下载)
来源仓库:https://github.com/weilixiong/xhs-download
安装命令:
openclaw skills install xhs-download
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install xhs-download

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

小红书笔记批量下载。通过已登录 Chrome 的 DevTools Protocol 自动化下载小红书笔记(图片+文字)到本地。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install xhs-download;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要执行命令,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

xhs-download 怎么安装?

在终端执行 openclaw skills install xhs-download。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

xhs-download 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

xhs-download 需要什么权限?

权限级别是执行命令。安装流程涉及命令执行,可能通过 openclaw skills install xhs-download 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

xhs-download 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

xhs-download 用的人多吗?

公开数据是累计安装 2,046 次,近一周安装 87 次,下载 717 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

xhs-download 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要执行命令,装到常用环境前要先评估影响面。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 不能接受 Skill 在你机器上执行命令的人。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
xhs-download

xhs 下载 · 本页

2,046—执行命令MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
xhs-download
description
小红书笔记批量下载。通过已登录 Chrome 的 DevTools Protocol 自动化下载小红书笔记(图片+文字)到本地。

小红书笔记批量下载

通过 Chrome DevTools Protocol (CDP) 批量下载小红书笔记到本地文件夹。

前置条件

  1. Chrome 已登录小红书(任何方式启动均可)
  2. Chrome 开启远程调试:启动时加 --remote-debugging-port=9222
  3. Python3 环境:pip3 install websocket-client requests
如果 Chrome 已启动但没开调试端口,关闭后重启即可。

使用方法(4步)

第1步:找到目标账号的 profile_id

打开小红书网页版,进入目标账号主页,复制 URL 最后一段:

https://www.xiaohongshu.com/user/profile/64902d2d000000001c0294eb
                                                 ↑ 这个就是 profile_id

第2步:获取 Chrome tab_id

在终端运行:

curl -s http://127.0.0.1:9222/json | python3 -m json.tool | grep -E '"id"|"url"'

找到包含 xiaohongshu.com 的那条记录,复制其 id 值。

第3步:修改脚本配置

将下方脚本开头的三个变量改成你的值:

变量填什么示例
PROFILE_ID第1步获取的账号ID"64902d2d000000001c0294eb"
TAB_ID第2步获取的tab ID"4C23291E2F8B1524..."
SAVE_DIR你想保存到的文件夹"~/Downloads/我的笔记/"

第4步:运行脚本

把脚本保存为 download.py,然后运行:

python3 download.py

完整脚本

import json, time, requests, os, subprocess, websocket, re

# ===== 改这里 =====
PROFILE_ID = "你的目标账号ID"
TAB_ID = "你的Chrome tab_id"
SAVE_DIR = "~/Downloads/你的文件夹/"
# =================

SAVE_DIR = os.path.expanduser(SAVE_DIR)
os.makedirs(SAVE_DIR, exist_ok=True)

def send(ws, method, params={}):
    """CDP 命令发送。3个参数:ws连接对象, 方法名, 参数字典"""
    msg_id = int(time.time()*1000) % 100000
    msg = {"id": msg_id, "method": method, "params": params}
    ws.send(json.dumps(msg))
    while True:
        resp = json.loads(ws.recv())
        if resp.get("id") == msg_id:
            return resp

def download_image(url, path):
    """下载图片,必须带 Referer"""
    r = requests.get(url, headers={"Referer": "https://www.xiaohongshu.com/"}, timeout=30)
    if len(r.content) > 100:
        with open(path, 'wb') as f:
            f.write(r.content)
        return True
    return False

# 1. 连接 Chrome
ws = websocket.create_connection(
    f"ws://127.0.0.1:9222/devtools/page/{TAB_ID}", timeout=30)
print(f"已连接 Chrome tab: {TAB_ID}")

# 2. 导航到目标主页
url = f"https://www.xiaohongshu.com/user/profile/{PROFILE_ID}"
send(ws, "Page.navigate", {"url": url})
time.sleep(6)
print(f"已导航到: {url}")

# 3. 滚动加载所有笔记(30次,覆盖绝大多数账号)
print("滚动加载中...")
for i in range(30):
    send(ws, "Input.synthesizeScrollGesture", {
        "x": 500, "y": 600,
        "xDistance": 0, "yDistance": -800,
        "speed": 2000
    })
    time.sleep(2)
    if (i + 1) % 10 == 0:
        print(f"  已滚动 {i+1}/30 次")

# 4. 从 DOM 提取笔记列表
result = send(ws, "Runtime.evaluate", {"expression": """
(() => {
    const cards = document.querySelectorAll(".feeds-container .note-item");
    return JSON.stringify(Array.from(cards).map(c => {
        const a = c.querySelector("a[href*='/explore/']");
        return {
            href: a ? a.getAttribute("href") : "",
            title: a ? a.innerText.trim().substring(0, 60) : ""
        };
    }));
})()
"""})
notes = json.loads(result["result"]["result"]["value"])
print(f"\
找到 {len(notes)} 篇笔记\
")

# 5. 从 __INITIAL_STATE__ 获取所有笔记的 xsecToken
state_result = send(ws, "Runtime.evaluate", {"expression": """
(() => {
    const state = window.__INITIAL_STATE__ || {};
    const user = state.user || {};
    const notes = user.notes || {};
    const items = (notes._value && notes._value.items) ? notes._value.items : [];
    return JSON.stringify(items.map(n => ({
        id: (n.note && n.note.id) || '',
        xsecToken: (n.note && n.note.xsecToken) || ''
    })));
})()
"""})
token_map = {}
for item in json.loads(state_result["result"]["result"]["value"]):
    if item["id"]:
        token_map[item["id"]] = item["xsecToken"]

# 6. 逐篇下载
downloaded = 0
skipped = 0
for note in notes:
    href = note.get("href", "")
    title = note.get("title", "").strip()
    if not href or not title:
        continue

    note_dir = os.path.join(SAVE_DIR, title)
    if os.path.exists(note_dir):
        print(f"⏭ 跳过(已存在): {title[:30]}")
        skipped += 1
        continue

    os.makedirs(note_dir, exist_ok=True)

    # 提取 note_id
    m = re.search(r'/explore/([a-f0-9]+)', href)
    note_id = m.group(1) if m else ""
    if not note_id:
        continue

    xsec_token = token_map.get(note_id, "")

    # 导航到详情页
    if xsec_token:
        detail_url = f"https://www.xiaohongshu.com/explore/{note_id}?xsec_token={xsec_token}"
    else:
        detail_url = f"https://www.xiaohongshu.com/explore/{note_id}"
    send(ws, "Page.navigate", {"url": detail_url})
    time.sleep(4)

    # 提取图片列表
    img_result = send(ws, "Runtime.evaluate", {"expression": """
    (() => {
        const swiper = document.querySelector('.swiper-wrapper');
        const imgs = swiper ? swiper.querySelectorAll('img') : [];
        return JSON.stringify(Array.from(imgs).map((img, i) => ({
            i, src: img.src
        })));
    })()
    """})
    images = json.loads(img_result["result"]["result"]["value"])

    # 下载图片
    img_count = 0
    for img in images:
        src = img.get("src", "")
        if src:
            path = os.path.join(note_dir, f"{img['i']+1}.jpg")
            if download_image(src, path):
                img_count += 1

    # 提取正文
    text_result = send(ws, "Runtime.evaluate", {"expression": """
    (() => {
        const desc = document.querySelector('.note-content .desc');
        return desc ? desc.innerText : document.title || '';
    })()
    """})
    text = text_result["result"]["result"].get("value", "")
    with open(os.path.join(note_dir, "内容.txt"), "w", encoding="utf-8") as f:
        f.write(text)

    downloaded += 1
    print(f"✅ {title[:30]}... ({img_count}张图)")

ws.close()
print(f"\
{'='*40}")
print(f"完成!下载 {downloaded} 篇,跳过 {skipped} 篇")
print(f"保存位置: {SAVE_DIR}")

输出格式

每篇笔记一个文件夹:

~/Downloads/你的文件夹/
├── 笔记标题1/
│   ├── 内容.txt
│   ├── 1.jpg
│   ├── 2.jpg
│   └── 3.jpg
└── 笔记标题2/
    ├── 内容.txt
    └── 1.jpg

常见问题

问题原因解决
Connection refusedChrome 没开调试端口加 --remote-debugging-port=9222 重启
图片下载失败/403缺少 Referer脚本已自带,别删 headers
笔记数量比预期少滚动次数不够把 30 改成 50
send() 不返回参数不对必须是 3 个参数:send(ws, method, params={})
websocket 模块找不到没装依赖pip3 install websocket-client

注意事项

  • 脚本会自动跳过已下载的笔记(文件夹已存在)
  • 每次导航详情页需要 4 秒等待加载
  • 图片下载必须带 Referer 头,否则 403
  • 大批量下载建议分段运行(避免被限流)

平台分布

OpenClaw

83.99%
按下载量换算602

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

执行命令

安装流程涉及命令执行,可能通过 openclaw skills install xhs-download 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills