Bundle
dsh-community-listening
社交评论挖掘与分析工具集:8 平台评论采集、平台搜索发现、语料落盘、情感/主题/去重分析、报告导出
- Source
- tyx6661234
- stars
- 1 stars
- License
- MIT
- Updated
- Updated 5 days ago
Readme
# dsh-community-listening
面向 DeepSeek Harness (DSH) 的社交评论研究插件。它提供平台内容发现、公开评论采集、语料管理、情感分析、近似去重、主题聚类和 Markdown 报告导出能力。
`dsh-community-listening` 是一个标准 DSH bundle:只注入官方 `tools` service,可运行在普通 DSH profile 与 DSH Desktop profile 中。它不依赖 Electron、Desktop 私有 service、launcher bootstrap 或内部 shim。
## 功能
- 覆盖知乎、B 站、小红书、微博、抖音、快手、牛客和百度贴吧的评论采集。
- 为 B 站、小红书、微博、抖音、快手提供内容发现工具;抖音还支持读取用户近期作品。
- 将搜索结果和评论按主题保存为 JSONL 语料,并按 URL 与内容去重。
- 提供语料统计、词典/LLM 情感分析、SimHash 近似去重、embedding 或关键词主题聚类、报告导出。
- 对各平台维护独立的节流、冷却和通道健康状态;主通道失败时会在可用范围内自动降级。
## 支持范围
| 平台 | 内容发现 | 评论采集 | 浏览器与登录要求 |
| --- | --- | --- | --- |
| 知乎 | - | 问题页 | 浏览器;公开页面通常可读 |
| B 站 | 视频搜索 | 视频页 | 可匿名;可选 Cookie 改善 API 可用性 |
| 小红书 | 笔记搜索 | 笔记页 | 需要用户自己的登录态和有效 `xsec_token` |
| 微博 | 帖子搜索 | 详情页 | 浏览器;可用性取决于页面和平台状态 |
| 抖音 | 视频搜索、用户作品 | 视频页 | 浏览器;可用性取决于页面和平台状态 |
| 快手 | 视频搜索 | 视频页 | 浏览器;公开页面通常可读 |
| 牛客 | - | 讨论帖 | 浏览器;公开页面通常可读 |
| 百度贴吧 | - | 帖子页 | 浏览器;公开页面通常可读 |
对于其他网页,`collect_comments` 会尝试通过浏览器提取已加载的评论内容,但不保证适配效果。
## 前置条件
- Node.js `>= 20`。
- 可用的 DSH 或 DSH Desktop 环境。
- 已安装并可从 `PATH` 调用的 BrowserSkill CLI(`bsk`)。浏览器型采集依赖它连接用户的浏览器会话。
插件可在无浏览器连接时尝试拉起本机 Chrome;也可以关闭此行为,或指定浏览器可执行文件和 profile。使用需要登录的平台时,请只使用自己有权使用的浏览器 profile。
## 安装
### 一键安装(公开发布后)
```sh
dsh plugin --profile <name> add dsh-community-listening
```
将 `<name>` 替换为目标 DSH 或 DSH Desktop profile 的名称。安装后重启该 profile 即可加载插件。
### 源码部署
克隆仓库、构建 bundle,再从本地目录安装:
```sh
git clone https://github.com/tyx6661234/dsh-community-listening.git
cd dsh-community-listening
pnpm install --frozen-lockfile
pnpm build
dsh plugin --profile <name> add .
```
同一 bundle 可以安装到普通 DSH profile 或 DSH Desktop profile,不需要维护两套插件包。
### 本地开发
```sh
pnpm install
pnpm build
```
开发依赖仅用于构建和验证;发布包会保留 DSH 运行时所需的 peer dependencies,而不会把宿主运行时打进 bundle。
## 快速开始
在进行连续采集前,先查看平台状态:
```text
crawler_status()
```
搜索内容时传入 `topic` 会将发现结果写入该主题的语料目录:
```text
collect_bilibili_search({
keyword: "机械键盘",
topic: "mechanical-keyboards"
})
```
对搜索结果中的 URL 采集评论:
```text
collect_comments({
url: "<video-or-post-url>",
topic: "mechanical-keyboards"
})
```
之后可以统计、分析并导出报告:
```text
corpus_stats({ topic: "mechanical-keyboards" })
mine_sentiment({ topic: "mechanical-keyboards" })
dedupe_similar({ topic: "mechanical-keyboards" })
cluster_topics({ topic: "mechanical-keyboards" })
export_report({ topic: "mechanical-keyboards", report: "# Research report\n..." })
```
`cluster_topics` 读取主题下的 `article` 和 `page` 语料;评论情感分析则读取 `comment` 语料。也可以直接通过各工具的 `items` 参数分析未落盘的文本。
## 工具
### 采集与状态
| 工具 | 用途 |
| --- | --- |
| `crawler_status(platform?)` | 只读查看通道、最近结果、降级状态、冷却时间和历史趋势。 |
| `collect_comments(url, max_expand?, topic?)` | 按 URL 路由至平台适配器并采集评论;支持 `topic` 自动落盘。 |
| `collect_bilibili_search(keyword, topic?, limit?)` | 发现 B 站视频。 |
| `collect_xhs_search(keyword, topic?, limit?)` | 发现小红书笔记,并尽力提供可用 token 信息。 |
| `collect_weibo_search(keyword, topic?, limit?)` | 发现微博帖子。 |
| `collect_douyin_search(keyword, topic?, limit?, sort_type?, publish_time?)` | 发现抖音视频。 |
| `collect_douyin_user(userUrl, topic?, limit?)` | 读取一个抖音用户的近期作品。 |
| `collect_kuaishou_search(keyword, topic?, limit?)` | 发现快手视频。 |
采集结果会带上 `backend`、`fallbacks` 和 `degraded` 等字段。`degraded: true` 表示插件已从首选通道切换到兜底通道,不必然表示没有拿到结果。
### 语料与分析
| 工具 | 用途 |
| --- | --- |
| `save_corpus(topic, items, kind?)` | 手动追加文本到主题语料。 |
| `corpus_stats(topic)` | 统计语料数量、类型、来源策略和最近采集时间。 |
| `corpus_read(topic, kind?, limit?, offset?)` | 分页读取语料原文。 |
| `mine_sentiment(topic?, items?)` | 评论情感分桶与证据摘要;可选 LLM 校准。 |
| `dedupe_similar(topic?, items?, threshold?)` | 通过 SimHash 识别近似重复文本。 |
| `cluster_topics(topic?, items?, k?)` | 使用 embedding 或关键词聚类整理主题。 |
| `export_report(topic, report, overwrite?)` | 导出 Markdown 报告。 |
## 配置
在目标 profile 的插件配置中为 `dsh-community-listening` 添加 `config`。以下示例使用默认值;空字符串表示由环境、自动探测或会话目录决定。
```yaml
- id: dsh-community-listening
name: dsh-community-listening
config:
bskPath: bsk
bskTimeoutMs: 120000
maxCollectConcurrency: 3
envPath: ""
autoLaunchChrome: true
chromePath: ""
chromeProfileDir: ""
corpusDir: ""
pacingStateFile: ""
bilibiliCookie: ""
siliconflowKey: ""
siliconflowBaseUrl: ""
embeddingModel: ""
bypassProxyHosts: []
zhihuMaxAnswers: 50
zhihuMaxAnswerComments: 10
bilibiliMaxComments: 100
bilibiliMaxReplyComments: 20
```
| 字段 | 默认值与边界 | 说明 |
| --- | --- | --- |
| `bskPath` | `bsk` | BrowserSkill CLI 路径。 |
| `bskTimeoutMs` | `120000`,`1000`-`600000` | 单次 BrowserSkill 命令超时,单位毫秒。 |
| `maxCollectConcurrency` | `3`,`1`-`5` | 浏览器型采集的全局并发上限。 |
| `envPath` | 空 | 可选 `.env` 文件;空值时只读取进程环境变量。 |
| `autoLaunchChrome` | `true` | 无连接时是否尝试启动本机浏览器。 |
| `chromePath` / `chromeProfileDir` | 空 | 覆盖自动探测的浏览器路径或 profile。 |
| `corpusDir` | 空 | 语料根目录;也可用 `DSH_INSIGHT_CORPUS_DIR` 设置。 |
| `pacingStateFile` | 空 | 节流状态文件;也可用 `DSH_INSIGHT_PACING_STATE` 设置。 |
| `bilibiliCookie` | 空 | 可选 B 站 Cookie;也可用 `BILIBILI_COOKIE` 设置。不要提交到仓库。 |
| `siliconflowKey` / `siliconflowBaseUrl` / `embeddingModel` | 空 | 可选 embedding 覆盖;未设置时读取环境或 `envPath`。 |
| `bypassProxyHosts` | `[]` | 需要直连的额外域名后缀。 |
| `zhihuMaxAnswers` | `50`,`1`-`200` | 知乎问题页最多处理的回答数。 |
| `zhihuMaxAnswerComments` | `10`,`0`-`100` | 读取评论的知乎回答数量。 |
| `bilibiliMaxComments` | `100`,`1`-`500` | B 站主评论与回复的合计上限。 |
| `bilibiliMaxReplyComments` | `20`,`0`-`100` | 尝试读取楼中楼的主评论数量。 |
可选的 LLM 与 embedding 配置支持显式插件配置、进程环境变量和 `envPath` 中的变量。常用变量包括:
```text
OPENCODE_API_BASE_URL
OPENCODE_API_KEY
OPENCODE_FREE_MODELS
LLM_BASE_URL
OPENAI_API_KEYS
LLM_MODEL_LITE
SILICONFLOW_API_KEY
SILICONFLOW_BASE_URL
EMBEDDING_MODEL
```
LLM 或 embedding 不可用时,插件会使用规则或关键词路径降级,并在结果中标记相关状态。凭据只应存储在本机受保护的配置或环境中,绝不能提交到 Git、issue 或日志。
## 运行行为与限制
- 插件只处理公开可读内容,且只复用用户自己的浏览器登录态。
- 不破解验证码、不绕过登录墙、不伪造设备身份,也不提供规避平台访问限制的功能。
- 遇到登录墙、验证码、限流或浏览器不可用时,工具会停止、返回错误或进入冷却;请勿在冷却期间反复重试同一平台。
- 小红书需要登录态和 `xsec_token`。搜索结果中没有有效 token 或平台不返回公开内容时,评论采集可能为空或失败。
- 平台页面、接口、登录策略和访问限制可能随时变化,公开页面可访问不等于持续可采集。
- 自动降级优先保证任务可观测性:请通过 `crawler_status`、返回的 `backend` 和 `degraded` 判断当前通道状态。
使用本插件前,请确认你的用途符合目标平台规则、适用法律以及所在组织的数据处理要求。
## 数据文件
默认情况下,主题数据保存到当前 DSH 会话工作目录下;可通过 `corpusDir` 指定语料根目录。一个主题的典型结构如下:
```text
<corpus-root>/insight-workspace/<topic>/
corpus.jsonl # 搜索结果、页面与评论语料
analysis.json # 最近一次分析快照
report.md # export_report 导出的报告
```
节流状态和通道健康状态分别存放在 `.pacing.json` 与 `.crawler-health.json`。这些是本地运行状态,不应提交或发布。
根目录中的 `agent-skill.json` 是供本地 Agent 检索使用的元数据,不是 DSH Desktop manifest,也不替代 `package.json` 与 `cordis.patch.yml` 的 bundle 声明。
## 开发与验证
```sh
pnpm install --frozen-lockfile
pnpm typecheck
pnpm test
pnpm build
pnpm plugin:check
pnpm pack --dry-run
```
`plugin:check` 会验证 bundle 入口、类型入口、patch manifest、发布文件和归档排除规则。提交前还应分别在普通 DSH profile 与 DSH Desktop profile 中完成一次加载和重启 smoke test。
### 发布
发布前请更新严格的 SemVer 版本号,并确认上述验证全部通过:
```sh
pnpm version patch
pnpm install --frozen-lockfile
pnpm typecheck
pnpm test
pnpm build
pnpm plugin:check
pnpm pack --dry-run
```
确认包内容无误后,再按组织的 npm 发布流程执行公开发布。
## 贡献
欢迎提交 issue 和 pull request。新增或修改平台适配器时,请:
- 保持采集逻辑在公开内容和用户授权的浏览器会话范围内。
- 为 URL 路由、解析、错误与降级行为补充单元测试。
- 不提交 Cookie、API key、语料、状态文件、浏览器 profile 或本机绝对路径。
- 在修改发布相关文件后运行 `pnpm plugin:check` 与 `pnpm pack --dry-run`。
## 许可证
[MIT](LICENSE)。目标平台内容及其使用仍受各平台规则和适用法律约束。
Install
dsh plugin --profile web add github:tyx6661234/dsh-community-listening
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-community-listening from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.