@clawhub-weilixiong-e2b100761e
小红书笔记批量下载。通过已登录 Chrome 的 DevTools Protocol 自动化下载小红书笔记(图片+文字)到本地。
---
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
在终端运行:
```bash
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`,然后运行:
```bash
python3 download.py
```
## 完整脚本
```python
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"\n找到 {len(notes)} 篇笔记\n")
# 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"\n{'='*40}")
print(f"完成!下载 {downloaded} 篇,跳过 {skipped} 篇")
print(f"保存位置: {SAVE_DIR}")
```
## 输出格式
每篇笔记一个文件夹:
```
~/Downloads/你的文件夹/
├── 笔记标题1/
│ ├── 内容.txt
│ ├── 1.jpg
│ ├── 2.jpg
│ └── 3.jpg
└── 笔记标题2/
├── 内容.txt
└── 1.jpg
```
## 常见问题
| 问题 | 原因 | 解决 |
|------|------|------|
| `Connection refused` | Chrome 没开调试端口 | 加 `--remote-debugging-port=9222` 重启 |
| 图片下载失败/403 | 缺少 Referer | 脚本已自带,别删 headers |
| 笔记数量比预期少 | 滚动次数不够 | 把 30 改成 50 |
| `send()` 不返回 | 参数不对 | 必须是 3 个参数:`send(ws, method, params={})` |
| `websocket` 模块找不到 | 没装依赖 | `pip3 install websocket-client` |
## 注意事项
- 脚本会自动跳过已下载的笔记(文件夹已存在)
- 每次导航详情页需要 4 秒等待加载
- 图片下载必须带 `Referer` 头,否则 403
- 大批量下载建议分段运行(避免被限流)
子代理任务拆分 + using-superpowers 技能执行。每次 spawn 子代理前必须遵守的铁律。结合 using-superpowers 和 subagent-tasking 规则。
---
name: subagent-tasking-with-superpowers
description: 子代理任务拆分 + using-superpowers 技能执行。每次 spawn 子代理前必须遵守的铁律。结合 using-superpowers 和 subagent-tasking 规则。
---
# 子代理任务拆分 + Superpowers 执行(铁律!)
## 核心原则
**每次 spawn 子代理前,必须执行以下流程。没有例外。不可跳过。不可 rationalize。**
---
## 流程图
```
用户任务 → 调用 using-superpowers 技能 → 检查相关技能 → 任务拆分自检 → 写 Task Brief → Spawn 子代理 → 验证结果 → 论坛留痕
```
---
## 第1步:调用 using-superpowers 技能
**必须先调用 using-superpowers 技能**,确认是否有其他相关技能适用。
- 如果有 1% 可能技能适用 → 调用它
- 不得跳过此步骤
- 不得 rationalize 说不需要
### Red Flags(禁止这样想!)
| 错误想法 | 现实 |
|---------|------|
| "这只是简单任务" | 简单任务也需要检查技能 |
| "我先看看情况" | 技能检查在看情况之前 |
| "我知道怎么做" | 知道 ≠ 用技能,必须调用 |
| "技能太复杂了" | 越复杂越要用技能 |
---
## 第2步:任务拆分自检
```
问自己3个问题:
1. 这个任务能拆成 2 个以上独立的子任务吗?
→ 能就拆,每个子任务单独 spawn
2. 子代理需要访问多少个文件/目录?
→ 超过 3 个就拆
3. 子代理需要执行多少步操作?
→ 超过 5 步就拆
```
---
## 第3步:写 Task Brief 文件
每个子代理的任务必须写入 `/tmp/tasks/` 目录:
```
/tmp/tasks/{任务名}_{时间戳}.md
内容格式:
# 任务名
- 目标:1句话描述
- 步骤:不超过3步
- 输出:返回什么格式
- 限制:不能做什么
```
---
## 第4步:Spawn 规则
| 规则 | 要求 |
|------|------|
| 每个 spawn 只做一件事 | ✅ |
| task 描述不超过 200 字 | ✅ |
| 复杂任务拆成多个 spawn | ✅ |
| 子代理模型与父代理一致 | ✅ |
| 完成后在论坛留痕 | ✅ |
---
## 示例
### ❌ 错误:任务太大
```
spawn tiechui: "检查论坛状态、修复问题、清理文件、更新文档"
```
### ✅ 正确:拆分
```
spawn tiechui-ops: "检查端口8808服务状态,报告HTTP响应码"
spawn tiechui-forum: "检查 posts.json 完整性,报告帖子数"
spawn tiechui-dev: "列出 workspace-tiechui 下的 .py 文件"
```
---
## 违反后果
- 子代理超时无输出
- 浪费 Token
- 任务失败需要重试
- 记录到 corrections.md
---
*规则创建时间:2026-04-12*
*维护人:铁头 🤖*
小红书笔记搬运到 Facebook 和 WordPress 的自动化流程。当用户要求搬运小红书笔记、发布小红书内容到 Facebook/WordPress 时使用。
---
name: xiaohongshu-搬运
description: 小红书笔记搬运到 Facebook 和 WordPress 的自动化流程。当用户要求搬运小红书笔记、发布小红书内容到 Facebook/WordPress 时使用。
---
# 小红书搬运 Skill
自动化搬运小红书笔记到 Facebook 和 WordPress。
## 工作流程
### 1. 小红书下载
**关键:必须先进入目标账户主页!**
```
1. 打开小红书网站
2. 进入目标账户主页(如 https://www.xiaohongshu.com/user/profile/64902d2d000000001c0294eb)
3. 在账户主页点击日记
4. 提取日记标题、内容、图片URL
```
### 2. 图片下载
```bash
# 带 Referer 头绕过防盗链
curl -H "Referer: https://www.xiaohongshu.com/" -o image.jpg "图片URL"
# webp 转 jpg(如果需要)
python3 -c "
from PIL import Image
img = Image.open('image.webp')
if img.mode == 'RGBA':
img = img.convert('RGB')
img.save('image.jpg', 'JPEG', quality=95)
"
```
### 3. 本地保存
```
~/Downloads/铁头/[账号主体]/[日记标题]/
├── 内容.txt
└── 图片*.jpg
```
**重要区分:**
| 用途 | 目录 |
|------|------|
| 日记永久保存 | `~/Downloads/铁头/[账号主体]/[日记标题]/` |
| 发布临时上传 | `/tmp/openclaw/uploads/` |
### 4. Facebook 发布
**推荐:Meta Business Suite**
URL: `https://business.facebook.com/latest/?asset_id=797431390121236`
流程:
1. 创建帖子 → 输入文字
2. 点击"添加照片" → browser upload
3. 使用 osascript 操作 macOS 文件对话框:
```bash
osascript << 'EOF'
tell application "System Events"
tell process "com.apple.appkit.xpc.openAndSavePanelService"
set frontmost to true
delay 0.5
-- Command+Shift+G
keystroke "g" using {command down, shift down}
delay 1.0
-- 输入路径
keystroke "/tmp/openclaw/uploads/"
delay 0.5
-- 确认
keystroke return
delay 0.5
-- 全选
keystroke "a" using command down
delay 0.3
-- 打开
keystroke return
end tell
end tell
EOF
```
### 5. WordPress 发布
**REST API**
```bash
curl -X POST "https://public-api.wordpress.com/wp/v2/sites/252834205/posts" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "标题",
"content": "内容(换行符需转换为<br/>或<p>)",
"status": "publish"
}'
```
## 常见问题
| 问题 | 解决方案 |
|------|----------|
| 图片下载失败 | 添加 `Referer: https://www.xiaohongshu.com/` |
| webp 无法打开 | Pillow 转换为 jpg |
| Facebook 上传卡住 | 使用 Meta Business Suite |
| WordPress JSON 解析失败 | 换行符转 `<br/>` 或 `<p>` |
| macOS 文件对话框无法操作 | 操作 `com.apple.appkit.xpc.openAndSavePanelService` 进程 |
## 账号信息
| 账号 | 小红书ID | 存放文件夹 |
|------|---------|-----------|
| 学未教育(上海) | 64902d2d000000001c0294eb | `~/Downloads/铁头/学未教育/` |
| 西安学未教育 | 652417a1000000002b0010e7 | `~/Downloads/铁头/西安学未/` |
## 发布顺序
```
Facebook → WordPress
```
**每次发布前必须清空 `/tmp/openclaw/uploads/` 目录!**
## 铁律
1. **任何数据操作必须先备份**
2. **长期任务做版本管理**
3. **所有任务进度在论坛留痕**
FILE:CHANGELOG.md
# 更新日志
## 1.0.0 (2026-03-31)
### 首次发布
**开发背景:**
- Christ 需要自动化搬运小红书笔记到 Facebook 和 WordPress
- 学未教育账号有大量笔记需要批量搬运
**开发过程:**
1. **需求分析** (2026-03-14)
- 确定目标账号:学未教育(上海)
- 确定发布平台:Facebook + WordPress
2. **流程验证** (2026-03-14 - 2026-03-26)
- 完成第1-11篇笔记搬运
- 验证图片下载方法(Referer 头)
- 验证 webp 转 jpg 方案
- 验证 Facebook 发布流程(Meta Business Suite)
- 验证 WordPress REST API
3. **踩坑记录** (2026-03-31)
- 发现账号混淆问题
- 发现目录混用问题
- 发现 macOS 文件对话框进程问题
- 发现 WordPress 换行符问题
4. **Skill 创建** (2026-03-31 18:24)
- 创建 SKILL.md 主文档
- 创建 scripts 脚本目录
- 创建 references 参考文档
### 功能清单
| 功能 | 状态 |
|------|------|
| 小红书笔记下载 | ✅ |
| 图片下载(带 Referer) | ✅ |
| webp 转 jpg | ✅ |
| Facebook 发布 | ✅ |
| WordPress 发布 | ✅ |
| macOS 文件对话框自动化 | ✅ |
### 已验证日记
- 第1-11篇:学未教育(上海)笔记
FILE:README.md
# 小红书笔记搬运 Skill
自动化搬运小红书笔记到 Facebook 和 WordPress。
## 功能
- 小红书笔记下载(图片 + 文字)
- 图片处理(webp → jpg,带 Referer)
- Facebook Meta Business Suite 自动发布
- WordPress REST API 发布
- macOS 文件对话框自动化
## 安装
```bash
clawhub install xiaohongshu-搬运
```
## 使用
### 基本流程
1. 进入小红书目标账户主页
2. 点击日记,提取内容
3. 下载图片到本地
4. 发布到 Facebook
5. 发布到 WordPress
### 目录结构
```
~/Downloads/铁头/[账号主体]/[日记标题]/
├── 内容.txt
└── 图片*.jpg
```
### 发布平台
| 平台 | 方式 |
|------|------|
| Facebook | Meta Business Suite + osascript |
| WordPress | REST API |
## 脚本
- `scripts/download_images.sh` - 图片下载
- `scripts/prepare_upload.py` - 上传准备
- `scripts/wp_publish.py` - WordPress 发布
## 参考
- `references/platforms.md` - 平台配置信息
- `references/pitfalls.md` - 踩坑记录
## 版本
- 1.0.0 (2026-03-31) - 首次发布
## 作者
铁铁团队 - 铁头 🤖
FILE:package.json
{
"name": "小红书笔记搬运",
"slug": "xiaohongshu-transfer",
"version": "1.0.0",
"description": "自动化搬运小红书笔记到 Facebook 和 WordPress",
"author": "铁铁团队",
"license": "MIT",
"keywords": ["xiaohongshu", "小红书", "搬运", "facebook", "wordpress"],
"repository": "",
"created": "2026-03-31",
"scripts": [
"scripts/download_images.sh",
"scripts/prepare_upload.py",
"scripts/wp_publish.py"
],
"references": [
"references/platforms.md",
"references/pitfalls.md"
]
}
FILE:references/pitfalls.md
# 小红书搬运踩坑记录
## 🔴 必须先进入目标账户主页
**错误:** 直接在小红书首页/推荐页点击日记下载
**正确:** 先进入目标账户主页,再在主页中点击日记
```
正确流程:
小红书首页 → 搜索账户名 → 进入账户主页 → 点击日记
```
## 🔴 图片目录不要混用
| 目录 | 用途 | 说明 |
|------|------|------|
| `~/Downloads/铁头/[账号]/[标题]/` | **永久保存** | 日记原始内容 |
| `/tmp/openclaw/uploads/` | **临时上传** | 发布时临时存放,每次清空 |
**教训:** 不要用上传目录保存日记,多任务时容易混乱
## 🔴 每次发布前必须清空上传目录
```bash
rm -rf /tmp/openclaw/uploads/*
```
## 🔴 macOS 文件对话框属于独立进程
**错误:** 用 `tell process "Google Chrome"` 操作文件对话框
**正确:** 用 `tell process "com.apple.appkit.xpc.openAndSavePanelService"`
## 🔴 WordPress 换行符需转换
**错误:** 直接发送带换行符的内容,JSON 解析失败
**正确:** 换行符转换为 `<br/>` 或 `<p>` 标签
## 🔴 图片下载需带 Referer
```bash
curl -H "Referer: https://www.xiaohongshu.com/" -o image.jpg "$URL"
```
## 🔴 webp 格式需转换
小红书部分图片是 webp 格式,WordPress 不支持,需转换为 jpg
FILE:references/platforms.md
# 小红书搬运 Skill - 参考文档
## 常用账号
| 账号名称 | 小红书ID | 主页URL |
|---------|---------|---------|
| 学未教育(上海) | 64902d2d000000001c0294eb | https://www.xiaohongshu.com/user/profile/64902d2d000000001c0294eb |
| 西安学未教育 | 652417a1000000002b0010e7 | https://www.xiaohongshu.com/user/profile/652417a1000000002b0010e7 |
## 发布平台配置
### Facebook (Meta Business Suite)
- 主页ID: 797431390121236
- 主页名: Easy Talk
- URL: https://business.facebook.com/latest/?asset_id=797431390121236
### WordPress
- Blog ID: 252834205
- 站点: https://studyfuture0.wordpress.com
- API: https://public-api.wordpress.com/wp/v2/sites/252834205/posts
## 图片处理命令
```bash
# 下载图片(带 Referer)
curl -H "Referer: https://www.xiaohongshu.com/" -o image.jpg "URL"
# webp 转 jpg
python3 -c "
from PIL import Image
img = Image.open('input.webp').convert('RGB')
img.save('output.jpg', 'JPEG', quality=95)
"
```
## macOS 文件对话框自动化
```bash
osascript << 'EOF'
tell application "System Events"
tell process "com.apple.appkit.xpc.openAndSavePanelService"
set frontmost to true
keystroke "g" using {command down, shift down}
delay 1
keystroke "/tmp/openclaw/uploads/"
keystroke return
delay 0.5
keystroke "a" using command down
keystroke return
end tell
end tell
EOF
```
## 已验证的发布流程
1. 小红书 → 进入账户主页 → 点击日记
2. 下载图片到 `~/Downloads/铁头/[账号]/[标题]/`
3. 复制到 `/tmp/openclaw/uploads/`
4. Meta Business Suite → 添加照片 → osascript 操作
5. WordPress API → 发布文章
FILE:scripts/download_images.sh
#!/bin/bash
# 小红书图片下载脚本
# 用法: ./download_images.sh <日记标题> <图片URL列表>
TITLE="$1"
ACCOUNT="学未教育"
SAVE_DIR="$HOME/Downloads/铁头/$ACCOUNT/$TITLE"
UPLOAD_DIR="/tmp/openclaw/uploads"
# 创建保存目录
mkdir -p "$SAVE_DIR"
# 清空上传目录
rm -rf "$UPLOAD_DIR/*"
mkdir -p "$UPLOAD_DIR"
# 下载图片
for url in "2"; do
filename=$(basename "$url" | sed 's/webp$/jpg/')
# 带 Referer 下载
curl -H "Referer: https://www.xiaohongshu.com/" \
-o "$SAVE_DIR/$filename" "$url"
# 复制到上传目录
cp "$SAVE_DIR/$filename" "$UPLOAD_DIR/"
echo "下载: $filename"
done
echo "保存位置: $SAVE_DIR"
echo "上传位置: $UPLOAD_DIR"
FILE:scripts/prepare_upload.py
#!/usr/bin/env python3
"""小红书笔记信息提取"""
from PIL import Image
import os
import sys
def convert_webp_to_jpg(webp_path, jpg_path, quality=95):
"""转换 webp 到 jpg"""
img = Image.open(webp_path)
if img.mode == 'RGBA':
img = img.convert('RGB')
img.save(jpg_path, 'JPEG', quality=quality)
return jpg_path
def prepare_upload_dir(save_dir, upload_dir="/tmp/openclaw/uploads"):
"""准备上传目录(清空并复制图片)"""
# 清空上传目录
if os.path.exists(upload_dir):
for f in os.listdir(upload_dir):
fp = os.path.join(upload_dir, f)
if os.path.isfile(fp):
os.remove(fp)
else:
os.makedirs(upload_dir)
# 复制图片
for f in os.listdir(save_dir):
if f.lower().endswith(('.jpg', '.jpeg', '.png')):
src = os.path.join(save_dir, f)
dst = os.path.join(upload_dir, f)
with open(src, 'rb') as s:
with open(dst, 'wb') as d:
d.write(s.read())
print(f"复制: {f}")
return upload_dir
if __name__ == "__main__":
if len(sys.argv) < 2:
print("用法: python prepare_upload.py <日记保存目录>")
sys.exit(1)
save_dir = sys.argv[1]
upload_dir = prepare_upload_dir(save_dir)
print(f"✅ 上传目录已准备: {upload_dir}")
print(f"图片数量: {len(os.listdir(upload_dir))}")
FILE:scripts/wp_publish.py
#!/usr/bin/env python3
"""小红书笔记发布到 WordPress"""
import os
import sys
import requests
import json
# WordPress 配置
WP_BLOG_ID = "252834205"
WP_TOKEN = os.environ.get("WP_TOKEN", "")
def publish_to_wordpress(title, content, status="publish"):
"""发布文章到 WordPress"""
# 换行符转换为 HTML
content_html = content.replace('\n', '<br/>')
url = f"https://public-api.wordpress.com/wp/v2/sites/{WP_BLOG_ID}/posts"
headers = {
"Authorization": f"Bearer {WP_TOKEN}",
"Content-Type": "application/json"
}
data = {
"title": title,
"content": content_html,
"status": status
}
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200 or response.status_code == 201:
result = response.json()
return result.get("ID")
else:
print(f"发布失败: {response.status_code}")
print(response.text)
return None
if __name__ == "__main__":
if len(sys.argv) < 3:
print("用法: python wp_publish.py <标题> <内容文件>")
sys.exit(1)
title = sys.argv[1]
content_file = sys.argv[2]
with open(content_file, 'r', encoding='utf-8') as f:
content = f.read()
post_id = publish_to_wordpress(title, content)
if post_id:
print(f"✅ WordPress 文章ID: {post_id}")