xhs-kit 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xhs_kit-0.1.0/.claude/skills/xhs-kit/SKILL.md +350 -0
- xhs_kit-0.1.0/.github/workflows/publish.yml +55 -0
- xhs_kit-0.1.0/.github/workflows/test.yml +34 -0
- xhs_kit-0.1.0/.gitignore +38 -0
- xhs_kit-0.1.0/CLAUDE.md +139 -0
- xhs_kit-0.1.0/LICENSE +21 -0
- xhs_kit-0.1.0/PKG-INFO +522 -0
- xhs_kit-0.1.0/README.md +492 -0
- xhs_kit-0.1.0/pyproject.toml +61 -0
- xhs_kit-0.1.0/tests/__init__.py +1 -0
- xhs_kit-0.1.0/tests/conftest.py +86 -0
- xhs_kit-0.1.0/tests/test_cli.py +82 -0
- xhs_kit-0.1.0/tests/test_cookies.py +56 -0
- xhs_kit-0.1.0/tests/test_feed_detail.py +34 -0
- xhs_kit-0.1.0/tests/test_headless_guard.py +16 -0
- xhs_kit-0.1.0/tests/test_login.py +70 -0
- xhs_kit-0.1.0/tests/test_mcp_server.py +90 -0
- xhs_kit-0.1.0/tests/test_publish.py +33 -0
- xhs_kit-0.1.0/xhs_kit/__init__.py +3 -0
- xhs_kit-0.1.0/xhs_kit/po/__init__.py +6 -0
- xhs_kit-0.1.0/xhs_kit/po/browser.py +107 -0
- xhs_kit-0.1.0/xhs_kit/po/cli.py +574 -0
- xhs_kit-0.1.0/xhs_kit/po/client.py +360 -0
- xhs_kit-0.1.0/xhs_kit/po/cookies.py +62 -0
- xhs_kit-0.1.0/xhs_kit/po/feed_detail.py +289 -0
- xhs_kit-0.1.0/xhs_kit/po/feeds.py +88 -0
- xhs_kit-0.1.0/xhs_kit/po/interact.py +283 -0
- xhs_kit-0.1.0/xhs_kit/po/login.py +152 -0
- xhs_kit-0.1.0/xhs_kit/po/mcp_server.py +464 -0
- xhs_kit-0.1.0/xhs_kit/po/models.py +84 -0
- xhs_kit-0.1.0/xhs_kit/po/publish.py +381 -0
- xhs_kit-0.1.0/xhs_kit/po/search.py +142 -0
- xhs_kit-0.1.0/xhs_kit/po/text_card.py +252 -0
- xhs_kit-0.1.0/xhs_kit/po/user_profile.py +115 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: post-to-xhs
|
|
3
|
+
description: 小红书内容发布与管理助手。当用户要求登录、发小红书、搜索小红书、评论点赞收藏等任何小红书相关操作时使用。
|
|
4
|
+
metadata: {"openclaw": {"emoji": "📕", "requires": {"bins": ["convert"]}}}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# xhs-kit 使用方式
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
首次使用需要确认环境中有 Python 解释器。
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# 使用 pip 安装
|
|
15
|
+
pip install -U xhs-kit
|
|
16
|
+
|
|
17
|
+
# 安装 Playwright 浏览器(必需)
|
|
18
|
+
playwright install chromium
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## ⚠️ 重要:所有操作必须先登录
|
|
22
|
+
|
|
23
|
+
**小红书所有功能(发布、搜索、点赞、评论等)都需要先登录。**
|
|
24
|
+
|
|
25
|
+
### 1. 检查登录状态
|
|
26
|
+
|
|
27
|
+
执行任何操作前,先检查是否已登录:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
xhs-kit status
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- 输出 `✅ 已登录`:表示检测到 cookies 文件(quick 模式),通常可以继续操作
|
|
34
|
+
- 输出 `❌ 未登录`:表示未检测到 cookies 文件,必须先执行登录步骤
|
|
35
|
+
|
|
36
|
+
如果出现发布或者评论无结果等错误,说明 cookies 可能已过期或不可用,此时使用 verify 模式做真实校验:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
xhs-kit status --verify
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- 输出 `✅ 已登录(verify)`:cookies 仍可用,失败原因更可能是内容不可见或参数问题
|
|
43
|
+
- 输出 `❌ 未登录(verify)`:cookies 可能过期或被风控,需要重新登录
|
|
44
|
+
|
|
45
|
+
### 2. 登录方式(带 fallback 逻辑)
|
|
46
|
+
|
|
47
|
+
**推荐按以下顺序尝试登录:**
|
|
48
|
+
|
|
49
|
+
**方式一:终端二维码(Claude Code / Open Code 推荐)**
|
|
50
|
+
```bash
|
|
51
|
+
xhs-kit login-qrcode --terminal
|
|
52
|
+
```
|
|
53
|
+
- ⚠️ 需要安装 zbar 库才能解析二维码:
|
|
54
|
+
- macOS: `brew install zbar`
|
|
55
|
+
- Ubuntu: `apt install libzbar0`
|
|
56
|
+
- 如果未安装 zbar,会自动保存二维码图片并提示路径
|
|
57
|
+
- 用户扫码后按回车完成登录
|
|
58
|
+
- 如果终端显示失败,fallback 到方式二
|
|
59
|
+
|
|
60
|
+
**方式二:浏览器扫码登录(有图形界面的环境)**
|
|
61
|
+
```bash
|
|
62
|
+
xhs-kit login-browser
|
|
63
|
+
```
|
|
64
|
+
- 会弹出浏览器窗口供用户扫码
|
|
65
|
+
- 如果无法弹出浏览器(如远程服务器无图形界面),会提示使用二维码方式
|
|
66
|
+
|
|
67
|
+
**方式三:保存二维码图片(OpenClaw 推荐)**
|
|
68
|
+
```bash
|
|
69
|
+
xhs-kit login-qrcode --save /tmp/qrcode.png
|
|
70
|
+
```
|
|
71
|
+
- 将二维码图片发送给用户扫码
|
|
72
|
+
- 用户扫码后按回车完成登录
|
|
73
|
+
|
|
74
|
+
**如果以上方式都失败:**
|
|
75
|
+
- 提醒用户需要安装浏览器环境(Playwright + Chromium)
|
|
76
|
+
- 或需要图形界面环境
|
|
77
|
+
|
|
78
|
+
### 3. 登录参数说明
|
|
79
|
+
|
|
80
|
+
`login-qrcode` 参数:
|
|
81
|
+
|
|
82
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
83
|
+
|------|------|------|------|
|
|
84
|
+
| `-s/--save` | string | ❌ | 保存二维码图片到指定路径 |
|
|
85
|
+
| `--terminal/--no-terminal` | flag | ❌ | 是否在终端显示二维码(默认 terminal) |
|
|
86
|
+
|
|
87
|
+
登录成功后,cookies 会保存到本地文件,后续操作自动复用(有效期约 7-30 天)。
|
|
88
|
+
|
|
89
|
+
## ⚠️ Agent 运行建议(Claude Code / OpenClaw / MCP)
|
|
90
|
+
|
|
91
|
+
- **不要在每次调用前都执行 `status --verify`**,这会频繁打开页面,增加开销和风控风险。
|
|
92
|
+
- 默认使用 `xhs-kit status`(quick)即可。
|
|
93
|
+
- **仅当出现如下错误时**再执行 `xhs-kit status --verify`:
|
|
94
|
+
- `未找到笔记详情(可能 xsec_token 失效、未登录或触发风控)`
|
|
95
|
+
- 发布/点赞/评论失败且多次重试无效
|
|
96
|
+
- 如果 `status --verify` 判定未登录,再让用户执行 `xhs-kit login-browser`(需要人工扫码)。
|
|
97
|
+
|
|
98
|
+
## 发布操作
|
|
99
|
+
|
|
100
|
+
### 发布图文内容
|
|
101
|
+
|
|
102
|
+
命令:`xhs-kit publish`
|
|
103
|
+
|
|
104
|
+
**参数:**(`-i/--image`、`--tag` 可多次指定)
|
|
105
|
+
|
|
106
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
107
|
+
|------|------|------|------|
|
|
108
|
+
| `-t/--title` | string | ✅ | 文字标题 |
|
|
109
|
+
| `-c/--content` | string | ✅ | 文字正文内容 |
|
|
110
|
+
| `-i/--image` | string | ✅ | 图片路径(可多次指定) |
|
|
111
|
+
| `--tag` | string | ❌ | 话题标签(可多次指定) |
|
|
112
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
113
|
+
|
|
114
|
+
示例:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
xhs-kit publish -t "标题" -c "正文" -i /abs/1.jpg -i /abs/2.jpg --tag 旅行 --tag 美食
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 发布视频内容
|
|
121
|
+
|
|
122
|
+
命令:`xhs-kit publish-video`
|
|
123
|
+
|
|
124
|
+
**参数:**
|
|
125
|
+
|
|
126
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
127
|
+
|------|------|------|------|
|
|
128
|
+
| `-t/--title` | string | ✅ | 文字标题 |
|
|
129
|
+
| `-c/--content` | string | ✅ | 文字正文内容 |
|
|
130
|
+
| `-v/--video` | string | ✅ | 视频路径 |
|
|
131
|
+
| `--tag` | string | ❌ | 话题标签(可多次指定) |
|
|
132
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
133
|
+
|
|
134
|
+
示例:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
xhs-kit publish-video -t "标题" -c "正文" -v /abs/video.mp4
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 发布文字配图(文字卡片)
|
|
141
|
+
|
|
142
|
+
命令:`xhs-kit publish-text-card`
|
|
143
|
+
|
|
144
|
+
**参数:**(`-p/--page`、`--tag` 可多次指定)
|
|
145
|
+
|
|
146
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
147
|
+
|------|------|------|------|
|
|
148
|
+
| `-c/--cover` | string | ✅ | 封面文字 |
|
|
149
|
+
| `-p/--page` | string | ❌ | 正文页文字(可多次指定,最多17页) |
|
|
150
|
+
| `-s/--style` | string | ❌ | 卡片样式:基础\|边框\|备忘\|手写\|便签\|涂写\|简约\|光影\|几何 |
|
|
151
|
+
| `-t/--title` | string | ❌ | 文字标题 |
|
|
152
|
+
| `--content` | string | ❌ | 文字正文内容 |
|
|
153
|
+
| `--tag` | string | ❌ | 话题标签(可多次指定) |
|
|
154
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
155
|
+
|
|
156
|
+
示例:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
xhs-kit publish-text-card -c "封面" -p "第一页" -p "第二页" -s "基础" -t "笔记标题"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## 浏览/搜索
|
|
163
|
+
|
|
164
|
+
### 搜索内容
|
|
165
|
+
|
|
166
|
+
命令:`xhs-kit search`
|
|
167
|
+
|
|
168
|
+
**参数:**
|
|
169
|
+
|
|
170
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
171
|
+
|------|------|------|------|
|
|
172
|
+
| `-k/--keyword` | string | ✅ | 搜索关键词 |
|
|
173
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
174
|
+
|
|
175
|
+
**输出:**
|
|
176
|
+
|
|
177
|
+
命令会打印搜索到的笔记列表。每条结果会包含:
|
|
178
|
+
|
|
179
|
+
- `ID`:对应后续命令里的 `--feed-id`
|
|
180
|
+
- `xsec_token`:对应后续命令里的 `--xsec-token`
|
|
181
|
+
|
|
182
|
+
示例(截断):
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
1. 标题...
|
|
186
|
+
作者: xxx | 点赞: 123
|
|
187
|
+
ID: 1234567890abcdef
|
|
188
|
+
xsec_token: xsec_xxx
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 获取首页推荐列表
|
|
192
|
+
|
|
193
|
+
命令:`xhs-kit list-feeds`
|
|
194
|
+
|
|
195
|
+
**参数:**
|
|
196
|
+
|
|
197
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
198
|
+
|------|------|------|------|
|
|
199
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
200
|
+
|
|
201
|
+
**输出:** JSON 格式的推荐笔记列表
|
|
202
|
+
|
|
203
|
+
示例:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
xhs-kit list-feeds
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 获取笔记详情
|
|
210
|
+
|
|
211
|
+
命令:`xhs-kit detail`
|
|
212
|
+
|
|
213
|
+
**参数:**
|
|
214
|
+
|
|
215
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
216
|
+
|------|------|------|------|
|
|
217
|
+
| `--feed-id` | string | ✅ | 笔记 ID |
|
|
218
|
+
| `--xsec-token` | string | ✅ | 访问令牌 |
|
|
219
|
+
| `--load-comments` | flag | ❌ | 是否加载评论(默认 false) |
|
|
220
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
221
|
+
|
|
222
|
+
**输出:** JSON 格式的笔记详情(包括标题、内容、图片、互动数据等)
|
|
223
|
+
|
|
224
|
+
示例:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
xhs-kit detail --feed-id FEED_ID --xsec-token XSEC_TOKEN
|
|
228
|
+
xhs-kit detail --feed-id FEED_ID --xsec-token XSEC_TOKEN --load-comments
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### 获取用户主页
|
|
232
|
+
|
|
233
|
+
命令:`xhs-kit user-profile`
|
|
234
|
+
|
|
235
|
+
**参数:**
|
|
236
|
+
|
|
237
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
238
|
+
|------|------|------|------|
|
|
239
|
+
| `--user-id` | string | ✅ | 用户 ID |
|
|
240
|
+
| `--xsec-token` | string | ✅ | 访问令牌 |
|
|
241
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
242
|
+
|
|
243
|
+
**输出:** JSON 格式的用户主页信息
|
|
244
|
+
|
|
245
|
+
示例:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
xhs-kit user-profile --user-id USER_ID --xsec-token XSEC_TOKEN
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## 互动(点赞/收藏/评论)
|
|
252
|
+
|
|
253
|
+
以下命令需要你先从搜索结果或笔记链接中拿到 `feed_id` 和 `xsec_token`。
|
|
254
|
+
|
|
255
|
+
### 点赞/取消点赞
|
|
256
|
+
|
|
257
|
+
命令:`xhs-kit like`
|
|
258
|
+
|
|
259
|
+
**参数:**
|
|
260
|
+
|
|
261
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
262
|
+
|------|------|------|------|
|
|
263
|
+
| `--feed-id` | string | ✅ | 笔记 ID |
|
|
264
|
+
| `--xsec-token` | string | ✅ | 访问令牌 |
|
|
265
|
+
| `--unlike` | flag | ❌ | 取消点赞(默认 false 为点赞) |
|
|
266
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
267
|
+
|
|
268
|
+
示例:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
xhs-kit like --feed-id FEED_ID --xsec-token XSEC_TOKEN
|
|
272
|
+
xhs-kit like --feed-id FEED_ID --xsec-token XSEC_TOKEN --unlike
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 收藏/取消收藏
|
|
276
|
+
|
|
277
|
+
命令:`xhs-kit favorite`
|
|
278
|
+
|
|
279
|
+
**参数:**
|
|
280
|
+
|
|
281
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
282
|
+
|------|------|------|------|
|
|
283
|
+
| `--feed-id` | string | ✅ | 笔记 ID |
|
|
284
|
+
| `--xsec-token` | string | ✅ | 访问令牌 |
|
|
285
|
+
| `--unfavorite` | flag | ❌ | 取消收藏(默认 false 为收藏) |
|
|
286
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
287
|
+
|
|
288
|
+
示例:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
xhs-kit favorite --feed-id FEED_ID --xsec-token XSEC_TOKEN
|
|
292
|
+
xhs-kit favorite --feed-id FEED_ID --xsec-token XSEC_TOKEN --unfavorite
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 发表评论
|
|
296
|
+
|
|
297
|
+
命令:`xhs-kit comment`
|
|
298
|
+
|
|
299
|
+
**参数:**
|
|
300
|
+
|
|
301
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
302
|
+
|------|------|------|------|
|
|
303
|
+
| `--feed-id` | string | ✅ | 笔记 ID |
|
|
304
|
+
| `--xsec-token` | string | ✅ | 访问令牌 |
|
|
305
|
+
| `-c/--content` | string | ✅ | 评论内容 |
|
|
306
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
307
|
+
|
|
308
|
+
示例:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
xhs-kit comment --feed-id FEED_ID --xsec-token XSEC_TOKEN -c "评论内容"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 回复评论
|
|
315
|
+
|
|
316
|
+
命令:`xhs-kit reply-comment`
|
|
317
|
+
|
|
318
|
+
**参数:**
|
|
319
|
+
|
|
320
|
+
| 参数 | 类型 | 必需 | 说明 |
|
|
321
|
+
|------|------|------|------|
|
|
322
|
+
| `--feed-id` | string | ✅ | 笔记 ID |
|
|
323
|
+
| `--xsec-token` | string | ✅ | 访问令牌 |
|
|
324
|
+
| `-c/--content` | string | ✅ | 回复内容 |
|
|
325
|
+
| `--comment-id` | string | ❌ | 目标评论 ID |
|
|
326
|
+
| `--user-id` | string | ❌ | 目标用户 ID |
|
|
327
|
+
| `--headless/--no-headless` | flag | ❌ | 是否无头模式(默认 headless) |
|
|
328
|
+
|
|
329
|
+
`--comment-id` 和 `--user-id` 至少需要提供一个。
|
|
330
|
+
|
|
331
|
+
示例:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
xhs-kit reply-comment --feed-id FEED_ID --xsec-token XSEC_TOKEN -c "回复内容" --comment-id COMMENT_ID
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
## 退出登录
|
|
339
|
+
|
|
340
|
+
命令:`xhs-kit logout`
|
|
341
|
+
|
|
342
|
+
会删除本地 cookies。
|
|
343
|
+
|
|
344
|
+
## (可选)MCP 模式
|
|
345
|
+
|
|
346
|
+
如果你的运行环境支持 MCP(例如 Claude Desktop / Cursor),可以启动 MCP:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
xhs-kit serve
|
|
350
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Set up Python
|
|
16
|
+
uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.11"
|
|
19
|
+
|
|
20
|
+
- name: Install build dependencies
|
|
21
|
+
run: |
|
|
22
|
+
python -m pip install --upgrade pip
|
|
23
|
+
pip install build
|
|
24
|
+
|
|
25
|
+
- name: Build package
|
|
26
|
+
run: python -m build
|
|
27
|
+
|
|
28
|
+
- name: Upload artifacts
|
|
29
|
+
uses: actions/upload-artifact@v4
|
|
30
|
+
with:
|
|
31
|
+
name: dist
|
|
32
|
+
path: dist/
|
|
33
|
+
|
|
34
|
+
publish:
|
|
35
|
+
needs: build
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
environment: pypi
|
|
38
|
+
permissions:
|
|
39
|
+
id-token: write
|
|
40
|
+
contents: write
|
|
41
|
+
steps:
|
|
42
|
+
- name: Download artifacts
|
|
43
|
+
uses: actions/download-artifact@v4
|
|
44
|
+
with:
|
|
45
|
+
name: dist
|
|
46
|
+
path: dist/
|
|
47
|
+
|
|
48
|
+
- name: Publish to PyPI
|
|
49
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
50
|
+
|
|
51
|
+
- name: Create GitHub Release
|
|
52
|
+
uses: softprops/action-gh-release@v1
|
|
53
|
+
with:
|
|
54
|
+
generate_release_notes: true
|
|
55
|
+
files: dist/*
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python 3.12
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
pip install -e ".[dev]"
|
|
25
|
+
pip install pytest-asyncio
|
|
26
|
+
playwright install chromium
|
|
27
|
+
|
|
28
|
+
- name: Run unit tests
|
|
29
|
+
run: |
|
|
30
|
+
pytest tests/test_cookies.py tests/test_cli.py tests/test_mcp_server.py -v
|
|
31
|
+
|
|
32
|
+
- name: Run login tests (without browser)
|
|
33
|
+
run: |
|
|
34
|
+
pytest tests/test_login.py -v --ignore-glob="*browser*" || true
|
xhs_kit-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
*.egg
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
venv/
|
|
14
|
+
.venv/
|
|
15
|
+
env/
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.idea/
|
|
19
|
+
.vscode/
|
|
20
|
+
*.swp
|
|
21
|
+
*.swo
|
|
22
|
+
|
|
23
|
+
# Testing
|
|
24
|
+
.pytest_cache/
|
|
25
|
+
.coverage
|
|
26
|
+
htmlcov/
|
|
27
|
+
|
|
28
|
+
# Logs
|
|
29
|
+
*.log
|
|
30
|
+
|
|
31
|
+
# Local config
|
|
32
|
+
.env
|
|
33
|
+
cookies.json
|
|
34
|
+
settings.local.json
|
|
35
|
+
|
|
36
|
+
# OS
|
|
37
|
+
.DS_Store
|
|
38
|
+
Thumbs.db
|
xhs_kit-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# xhs-kit 项目说明
|
|
2
|
+
|
|
3
|
+
## 项目概述
|
|
4
|
+
|
|
5
|
+
xhs-kit 是一个小红书自动化工具,基于 Playwright 浏览器自动化框架实现,支持通过 MCP 协议与 AI 助手集成。
|
|
6
|
+
|
|
7
|
+
**核心功能:**
|
|
8
|
+
- 扫码登录(浏览器/二维码两种模式)
|
|
9
|
+
- 发布图文、视频、文字配卡笔记
|
|
10
|
+
- 搜索内容、获取推荐流
|
|
11
|
+
- 点赞、收藏、评论、回复
|
|
12
|
+
- 获取笔记详情、用户主页
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 实现思路
|
|
16
|
+
|
|
17
|
+
### 1. 浏览器自动化核心
|
|
18
|
+
|
|
19
|
+
基于 **Playwright** 模拟真实浏览器行为:
|
|
20
|
+
|
|
21
|
+
- 创建持久化浏览器上下文(Persistent Context)
|
|
22
|
+
- 复用用户数据目录和 cookies,避免重复登录
|
|
23
|
+
- 模拟真实用户操作(点击、输入、滚动等)
|
|
24
|
+
- 拦截和分析网络请求,获取 API 数据
|
|
25
|
+
|
|
26
|
+
核心文件:`src/xhs_kit.po/browser.py`
|
|
27
|
+
|
|
28
|
+
### 2. 登录机制
|
|
29
|
+
|
|
30
|
+
小红书需要登录才能使用,实现了两种登录方式:
|
|
31
|
+
|
|
32
|
+
**浏览器扫码登录:**
|
|
33
|
+
- 弹出浏览器窗口访问小红书登录页
|
|
34
|
+
- 用户扫码后自动保存 cookies
|
|
35
|
+
|
|
36
|
+
**二维码登录(CLI 模式):**
|
|
37
|
+
- 通过截取登录页的二维码获取登录二维码
|
|
38
|
+
- 支持终端显示二维码(需安装 zbar)
|
|
39
|
+
- 支持保存二维码图片
|
|
40
|
+
- 轮询检测登录状态
|
|
41
|
+
|
|
42
|
+
核心文件:`src/xhs_kit.po/login.py`、`src/xhs_kit.po/cookies.py`
|
|
43
|
+
|
|
44
|
+
### 3. 内容发布
|
|
45
|
+
|
|
46
|
+
**图文发布:**
|
|
47
|
+
- 访问创作者发布页面
|
|
48
|
+
- 上传图片、填写标题和正文
|
|
49
|
+
- 支持添加话题标签
|
|
50
|
+
- 支持定时发布
|
|
51
|
+
|
|
52
|
+
**文字配卡发布:**
|
|
53
|
+
- 使用小红书自带的文字生图将文字渲染为卡片
|
|
54
|
+
- 支持多页、多种样式(基础、边框、手写等)
|
|
55
|
+
|
|
56
|
+
核心文件:`src/xhs_kit.po/publish.py`、`src/xhs_kit.po/text_card.py`
|
|
57
|
+
|
|
58
|
+
### 4. 数据获取
|
|
59
|
+
|
|
60
|
+
**搜索与推荐:**
|
|
61
|
+
- 访问搜索页面,模拟用户输入关键词
|
|
62
|
+
- 监听网络请求拦截搜索结果 API 响应
|
|
63
|
+
- 解析返回的 JSON 数据
|
|
64
|
+
|
|
65
|
+
**笔记详情、用户主页:**
|
|
66
|
+
- 直接访问笔记/用户页面 URL
|
|
67
|
+
- 监听 API 响应获取结构化数据
|
|
68
|
+
|
|
69
|
+
核心文件:`src/xhs_kit.po/search.py`、`src/xhs_kit.po/feeds.py`、`src/xhs_kit.po/feed_detail.py`
|
|
70
|
+
|
|
71
|
+
### 5. MCP 协议集成
|
|
72
|
+
|
|
73
|
+
将上述功能封装为 MCP 工具:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
MCP Server (stdio 模式)
|
|
77
|
+
├── login_with_browser
|
|
78
|
+
├── check_login_status
|
|
79
|
+
├── get_login_qrcode
|
|
80
|
+
├── publish_content
|
|
81
|
+
├── publish_text_card
|
|
82
|
+
├── publish_with_video
|
|
83
|
+
├── search_feeds
|
|
84
|
+
├── list_feeds
|
|
85
|
+
├── get_feed_detail
|
|
86
|
+
├── get_user_profile
|
|
87
|
+
├── like_feed / favorite_feed
|
|
88
|
+
└── post_comment / reply_comment
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
核心文件:`src/xhs_kit.po/mcp_server.py`
|
|
92
|
+
|
|
93
|
+
### 6. CLI 封装
|
|
94
|
+
|
|
95
|
+
提供命令行接口 `xhs-kit`,支持所有 MCP 工具的对应命令:
|
|
96
|
+
|
|
97
|
+
核心文件:`src/xhs_kit.po/cli.py`
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 开发规范
|
|
102
|
+
|
|
103
|
+
### 不修改已有功能
|
|
104
|
+
|
|
105
|
+
**本项目遵循「只修 bug,不改功能」原则:**
|
|
106
|
+
|
|
107
|
+
- ✅ 可以修复现有 bug
|
|
108
|
+
- ✅ 可以优化错误提示和日志
|
|
109
|
+
- ✅ 可以改进代码结构和注释
|
|
110
|
+
- ❌ 不要修改现有功能的业务逻辑
|
|
111
|
+
- ❌ 不要添加未经讨论的新功能
|
|
112
|
+
- ❌ 不要删除或重命名现有接口
|
|
113
|
+
|
|
114
|
+
### 添加新功能的流程
|
|
115
|
+
|
|
116
|
+
如果需要添加新功能:
|
|
117
|
+
|
|
118
|
+
1. 先与项目维护者讨论需求和设计
|
|
119
|
+
2. 确认后再进行实现
|
|
120
|
+
3. 新功能应通过 MCP 工具和 CLI 双暴露
|
|
121
|
+
|
|
122
|
+
### 代码结构
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
src/xhs_kit.po/
|
|
126
|
+
├── browser.py # Playwright 浏览器封装
|
|
127
|
+
├── cookies.py # Cookies 管理
|
|
128
|
+
├── login.py # 登录逻辑(浏览器/二维码)
|
|
129
|
+
├── publish.py # 发布图文/视频
|
|
130
|
+
├── text_card.py # 文字生图生成
|
|
131
|
+
├── search.py # 搜索功能
|
|
132
|
+
├── feeds.py # 推荐流获取
|
|
133
|
+
├── feed_detail.py # 笔记详情
|
|
134
|
+
├── user_profile.py # 用户主页
|
|
135
|
+
├── interact.py # 点赞/收藏/评论
|
|
136
|
+
├── models.py # Pydantic 数据模型
|
|
137
|
+
├── mcp_server.py # MCP 服务入口
|
|
138
|
+
└── cli.py # 命令行入口
|
|
139
|
+
```
|
xhs_kit-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|