mirror of
https://github.com/comeonzhj/Auto-Redbook-Skills.git
synced 2026-03-27 12:49:27 +08:00
Add files via upload
This commit is contained in:
202
scripts/publish_xhs.py
Normal file
202
scripts/publish_xhs.py
Normal file
@@ -0,0 +1,202 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
小红书笔记发布脚本
|
||||
将生成的图片卡片发布到小红书
|
||||
|
||||
使用方法:
|
||||
python publish_xhs.py --title "标题" --desc "描述" --images cover.png card_1.png card_2.png
|
||||
|
||||
环境变量:
|
||||
在同目录下创建 .env 文件,配置 XHS_COOKIE:
|
||||
XHS_COOKIE=your_cookie_string_here
|
||||
|
||||
依赖安装:
|
||||
pip install xhs python-dotenv
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from dotenv import load_dotenv
|
||||
from xhs import XhsClient
|
||||
except ImportError as e:
|
||||
print(f"缺少依赖: {e}")
|
||||
print("请运行: pip install xhs python-dotenv")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def load_cookie():
|
||||
"""从 .env 文件加载 Cookie"""
|
||||
# 尝试从当前目录加载 .env
|
||||
env_path = Path.cwd() / '.env'
|
||||
if env_path.exists():
|
||||
load_dotenv(env_path)
|
||||
|
||||
# 也尝试从脚本目录加载
|
||||
script_env = Path(__file__).parent.parent / '.env'
|
||||
if script_env.exists():
|
||||
load_dotenv(script_env)
|
||||
|
||||
cookie = os.getenv('XHS_COOKIE')
|
||||
if not cookie:
|
||||
print("❌ 错误: 未找到 XHS_COOKIE 环境变量")
|
||||
print("请在当前目录创建 .env 文件,添加以下内容:")
|
||||
print("XHS_COOKIE=your_cookie_string_here")
|
||||
sys.exit(1)
|
||||
|
||||
return cookie
|
||||
|
||||
|
||||
def create_client(cookie: str) -> XhsClient:
|
||||
"""创建小红书客户端"""
|
||||
try:
|
||||
# 使用本地签名
|
||||
from xhs.help import sign as local_sign
|
||||
|
||||
def sign_func(uri, data=None, a1="", web_session=""):
|
||||
return local_sign(uri, data, a1=a1)
|
||||
|
||||
client = XhsClient(cookie=cookie, sign=sign_func)
|
||||
return client
|
||||
except Exception as e:
|
||||
print(f"❌ 创建客户端失败: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def validate_images(image_paths: list) -> list:
|
||||
"""验证图片文件是否存在"""
|
||||
valid_images = []
|
||||
for path in image_paths:
|
||||
if os.path.exists(path):
|
||||
valid_images.append(os.path.abspath(path))
|
||||
else:
|
||||
print(f"⚠️ 警告: 图片不存在 - {path}")
|
||||
|
||||
if not valid_images:
|
||||
print("❌ 错误: 没有有效的图片文件")
|
||||
sys.exit(1)
|
||||
|
||||
return valid_images
|
||||
|
||||
|
||||
def publish_note(client: XhsClient, title: str, desc: str, images: list,
|
||||
is_private: bool = False, post_time: str = None):
|
||||
"""发布图文笔记"""
|
||||
try:
|
||||
print(f"\n🚀 准备发布笔记...")
|
||||
print(f" 📌 标题: {title}")
|
||||
print(f" 📝 描述: {desc[:50]}..." if len(desc) > 50 else f" 📝 描述: {desc}")
|
||||
print(f" 🖼️ 图片数量: {len(images)}")
|
||||
|
||||
result = client.create_image_note(
|
||||
title=title,
|
||||
desc=desc,
|
||||
files=images,
|
||||
is_private=is_private,
|
||||
post_time=post_time
|
||||
)
|
||||
|
||||
print("\n✨ 笔记发布成功!")
|
||||
if isinstance(result, dict):
|
||||
note_id = result.get('note_id') or result.get('id')
|
||||
if note_id:
|
||||
print(f" 📎 笔记ID: {note_id}")
|
||||
print(f" 🔗 链接: https://www.xiaohongshu.com/explore/{note_id}")
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ 发布失败: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def get_user_info(client: XhsClient):
|
||||
"""获取当前登录用户信息"""
|
||||
try:
|
||||
info = client.get_self_info()
|
||||
print(f"\n👤 当前用户: {info.get('nickname', '未知')}")
|
||||
return info
|
||||
except Exception as e:
|
||||
print(f"⚠️ 无法获取用户信息: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='将图片发布为小红书笔记'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--title', '-t',
|
||||
required=True,
|
||||
help='笔记标题(不超过20字)'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--desc', '-d',
|
||||
default='',
|
||||
help='笔记描述/正文内容'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--images', '-i',
|
||||
nargs='+',
|
||||
required=True,
|
||||
help='图片文件路径(可以多个)'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--private',
|
||||
action='store_true',
|
||||
help='是否设为私密笔记'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--post-time',
|
||||
default=None,
|
||||
help='定时发布时间(格式:2024-01-01 12:00:00)'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--dry-run',
|
||||
action='store_true',
|
||||
help='仅验证,不实际发布'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# 验证标题长度
|
||||
if len(args.title) > 20:
|
||||
print(f"⚠️ 警告: 标题超过20字,将被截断")
|
||||
args.title = args.title[:20]
|
||||
|
||||
# 加载 Cookie
|
||||
cookie = load_cookie()
|
||||
|
||||
# 验证图片
|
||||
valid_images = validate_images(args.images)
|
||||
|
||||
# 创建客户端
|
||||
client = create_client(cookie)
|
||||
|
||||
# 获取用户信息(验证 Cookie 有效性)
|
||||
get_user_info(client)
|
||||
|
||||
if args.dry_run:
|
||||
print("\n🔍 验证模式 - 不会实际发布")
|
||||
print(f" 📌 标题: {args.title}")
|
||||
print(f" 📝 描述: {args.desc}")
|
||||
print(f" 🖼️ 图片: {valid_images}")
|
||||
print("\n✅ 验证通过,可以发布")
|
||||
return
|
||||
|
||||
# 发布笔记
|
||||
publish_note(
|
||||
client=client,
|
||||
title=args.title,
|
||||
desc=args.desc,
|
||||
images=valid_images,
|
||||
is_private=args.private,
|
||||
post_time=args.post_time
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user