XHS-Downloader二次开发与定制
本文详细解析了XHS-Downloader项目的核心API接口、参数配置体系、Tampermonkey用户脚本集成以及批量处理与自动化脚本编写方法。文章深入探讨了XHS类的初始化参数、核心API方法、高级功能接口,并提供了丰富的配置选项和扩展开发示例,帮助开发者进行深度定制开发。
核心类XHS的API接口详解
XHS-Downloader项目的核心功能通过XHS类提供,该类封装了小红书作品数据采集、下载和管理的所有核心API。作为二次开发的基础,深入理解这些API接口对于定制化开发至关重要。
XHS类初始化参数详解
XHS类的构造函数提供了丰富的配置选项,支持高度定制化的数据采集和下载行为:
async with XHS(
work_path="D:\\", # 作品保存根路径
folder_name="Download", # 作品文件储存文件夹名称
name_format="作品标题 作品描述", # 文件命名格式
user_agent="", # 自定义User-Agent
cookie="", # 小红书Cookie
proxy=None, # 网络代理
timeout=10, # 请求超时时间(秒)
chunk=1024*1024, # 下载数据块大小(字节)
max_retry=5, # 最大重试次数
record_data=False, # 是否保存作品数据至文件
image_format="PNG", # 图片格式: AUTO/PNG/WEBP/JPEG/HEIC
image_download=True, # 图文作品下载开关
video_download=True, # 视频作品下载开关
live_download=False, # 动图文件下载开关
folder_mode=False, # 单个作品独立文件夹
download_record=True, # 记录下载成功作品ID
author_archive=False, # 作者作品单独文件夹
write_mtime=False, # 修改时间为发布时间
language="zh_CN", # 程序语言
read_cookie=None, # 读取浏览器Cookie
_print=True, # 打印日志开关
) as xhs:
# API调用代码
核心API方法详解
1. extract() - 作品数据提取与下载
extract()方法是核心的数据采集接口,支持批量处理多个作品链接:
async def extract(
self,
url: str, # 小红书作品链接(支持多个链接空格分隔)
download=False, # 是否下载作品文件
index: list | tuple = None, # 指定下载图片序号(图文作品)
log=None, # 日志记录器
bar=None, # 进度条对象
data=True, # 是否返回作品数据
) -> list[dict]:
返回值结构示例:
{
"作品ID": "65f8a9b200000000110a8c7c",
"作品类型": "视频",
"作品标题": "夏日海边度假穿搭分享",
"作品描述": "分享几套适合海边度假的穿搭...",
"发布时间": "2024-03-15 14:30:00",
"时间戳": 1710484200,
"作者昵称": "时尚博主小美",
"作者ID": "5e8f7b6a0000000001012345",
"作者链接": "https://www.xiaohongshu.com/user/profile/5e8f7b6a0000000001012345",
"点赞数量": 1250,
"收藏数量": 356,
"评论数量": 89,
"分享数量": 45,
"作品标签": ["穿搭", "度假", "海边", "夏日"],
"下载地址": ["https://sns-video-bd.xhscdn.com/...mp4"],
"动图地址": [None],
"采集时间": "2024-08-26 13:45:22"
}
2. extract_cli() - 命令行专用提取
专为命令行模式设计的提取方法,优化了输出和交互体验:
async def extract_cli(
self,
url: str, # 作品链接
download=True, # 默认下载文件
index: list | tuple = None, # 指定图片序号
log=None, # 日志记录器
bar=None, # 进度条
data=False, # 不返回数据(直接输出)
) -> None:
3. extract_links() - 链接提取与规范化
负责从输入文本中提取和规范化小红书作品链接:
async def extract_links(self, url: str, log) -> list:
支持多种链接格式:
- 标准探索页链接:
https://www.xiaohongshu.com/explore/作品ID - 发现页链接:
https://www.xiaohongshu.com/discovery/item/作品ID - 用户作品链接:
https://www.xiaohongshu.com/user/profile/作者ID/作品ID - 短链接:
https://xhslink.com/分享码
4. extract_id() - 作品ID提取
从链接中提取纯作品ID,用于去重和记录管理:
def extract_id(self, links: list[str]) -> list[str]:
高级功能API
5. monitor() - 剪贴板监听
实时监听剪贴板内容,自动处理小红书链接:
async def monitor(
self,
delay=1, # 检查间隔(秒)
download=False, # 是否自动下载
log=None, # 日志记录器
bar=None, # 进度条
data=True, # 是否返回数据
) -> None:
6. skip_download() - 下载记录检查
检查作品是否已下载,避免重复下载:
async def skip_download(self, id_: str) -> bool:
7. run_api_server() - API服务器启动
启动FastAPI服务器,提供RESTful API接口:
async def run_api_server(
self,
host="0.0.0.0", # 监听地址
port=5556, # 监听端口
log_level="info", # 日志级别
) -> None:
8. run_mcp_server() - MCP服务器启动
启动Model Context Protocol服务器,支持AI工具调用:
async def run_mcp_server(
self,
transport="streamable-http", # 传输协议
host="0.0.0.0", # 监听地址
port=5556, # 监听端口
log_level="INFO", # 日志级别
) -> None:
API调用流程示意图
错误处理机制
XHS类内置完善的错误处理机制:
- 网络请求重试:支持配置最大重试次数和超时时间
- 数据验证:对提取的数据进行完整性校验
- 异常捕获:捕获并记录处理过程中的各种异常
- 优雅降级:在部分功能失败时继续执行其他功能
性能优化特性
- 异步处理:基于asyncio实现高性能异步IO
- 连接池管理:复用HTTP连接减少开销
- 内存优化:流式下载大文件避免内存溢出
- 断点续传:支持下载中断后从断点继续
通过深入了解XHS类的API接口,开发者可以灵活地进行二次开发,实现定制化的数据采集和处理流程,满足各种业务场景的需求。
自定义参数配置与扩展开发
XHS-Downloader 提供了丰富的自定义参数配置选项,开发者可以通过多种方式进行灵活的二次开发和定制化配置。本文将深入探讨项目的参数配置体系、扩展开发方法以及如何根据特定需求进行定制化开发。
参数配置体系
XHS-Downloader 的参数配置体系采用分层设计,支持通过代码调用、命令行参数、配置文件等多种方式进行配置。
核心配置参数
项目提供了超过20个可配置参数,涵盖了下载行为、文件处理、网络请求等各个方面:
# 基础路径配置
work_path = "D:\\" # 作品数据/文件保存根路径
folder_name = "Download" # 作品文件储存文件夹名称
# 文件命名配置
name_format = "作品标题 作品描述" # 文件命名格式
# 网络配置
user_agent = "" # User-Agent
cookie = "" # 小红书网页版 Cookie
proxy = None # 网络代理
timeout = 5 # 请求超时时间(秒)
chunk = 1024 * 1024 * 10 # 下载数据块大小(字节)
max_retry = 2 # 最大重试次数
# 下载行为配置
record_data = False # 是否保存作品数据至文件
image_format = "WEBP" # 图文作品下载格式
folder_mode = False # 是否每个作品单独文件夹
image_download = True # 图文作品下载开关
video_download = True # 视频作品下载开关
live_download = False # 动图文件下载开关
download_record = True # 是否记录下载作品ID
# 高级配置
language = "zh_CN" # 程序语言
author_archive = True # 是否按作者分类存储
write_mtime = True # 是否修改文件时间为发布时间
read_cookie = None # 浏览器Cookie读取配置
配置参数详细说明
下表列出了所有可配置参数及其详细说明:
| 参数名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
work_path | str | 项目根路径 | 作品数据和文件的保存根路径 |
folder_name | str | "Download" | 作品文件储存文件夹名称 |
name_format | str | "发布时间 作者昵称 作品标题" | 文件命名格式模板 |
user_agent | str | None | 自定义User-Agent |
cookie | str | "" | 小红书网页版Cookie |
proxy | str/dict | None | 网络代理配置 |
timeout | int | 10 | 请求超时时间(秒) |
chunk | int | 1048576 | 下载数据块大小(字节) |
max_retry | int | 5 | 最大重试次数 |
record_data | bool | False | 是否保存作品数据至文件 |
image_format | str | "PNG" | 图文作品下载格式(AUTO/PNG/WEBP/JPEG/HEIC) |
folder_mode | bool | False | 是否将每个作品的文件储存至单独文件夹 |
image_download | bool | True | 图文作品下载开关 |
video_download | bool | True | 视频作品下载开关 |
live_download | bool | False | 动图文件下载开关 |
download_record | bool | True | 是否记录下载成功的作品ID |
language | str | "zh_CN" | 程序提示语言(zh_CN/en_US) |
author_archive | bool | False | 是否将每个作者的作品存至单独的文件夹 |
write_mtime | bool | False | 是否将作品文件的修改时间修改为作品的发布时间 |
read_cookie | int/str | None | 读取浏览器Cookie配置 |
扩展开发方法
1. 代码调用方式
通过直接实例化 XHS 类进行扩展开发是最灵活的方式:
from source import XHS
from asyncio import run
async def custom_download():
# 自定义配置实例
async with XHS(
work_path="D:\\XHS_Downloads",
folder_name="CustomDownload",
name_format="作者昵称_作品标题",
image_format="WEBP",
proxy="http://127.0.0.1:10808",
timeout=8,
max_retry=3,
author_archive=True,
write_mtime=True
) as xhs:
# 处理单个作品
result = await xhs.extract(
"https://www.xiaohongshu.com/explore/XXXXXXXX",
download=True,
index=[1, 3, 5] # 只下载第1、3、5张图片
)
print(result)
# 运行自定义下载
run(custom_download())
2. 命令行参数方式
支持通过命令行参数进行配置,适合脚本化操作:
# 基本下载命令
python main.py --url "https://www.xiaohongshu.com/explore/XXXXXXXX"
# 自定义参数下载
python main.py \
--url "https://www.xiaohongshu.com/explore/XXXXXXXX" \
--work_path "D:\\XHS_Downloads" \
--folder_name "CustomFolder" \
--image_format "WEBP" \
--timeout 8 \
--max_retry 3 \
--download
# 从浏览器读取Cookie
python main.py --browser_cookie Chrome --update_settings
3. API服务器模式
启动API服务器,支持HTTP请求调用:
from httpx import post
# 启动API服务器
# python main.py api
# API请求示例
server = "http://127.0.0.1:5556/xhs/detail"
data = {
"url": "https://www.xiaohongshu.com/explore/XXXXXXXX",
"download": True,
"index": [1, 2, 3],
"proxy": "http://127.0.0.1:10808",
"cookie": "your_cookie_here"
}
response = post(server, json=data, timeout=15)
print(response.json())
高级定制开发
自定义文件处理逻辑
可以通过继承和重写相关类来实现自定义的文件处理逻辑:
from source.application.download import Download
from pathlib import Path
class CustomDownload(Download):
async def run(self, urls, lives, index, nickname, filename, type_, mtime, log, bar):
# 自定义下载前处理
print(f"开始下载: {filename}")
# 调用父类方法
result = await super().run(urls, lives, index, nickname, filename, type_, mtime, log, bar)
# 自定义下载后处理
print(f"下载完成: {filename}")
return result
# 使用自定义下载类
async with XHS() as xhs:
xhs.download = CustomDownload(xhs.manager)
await xhs.extract(url, download=True)
自定义命名规则
实现自定义的文件命名规则:
from source.application.app import XHS
class CustomXHS(XHS):
def __naming_rules(self, data: dict) -> str:
# 自定义命名规则:作者ID_作品ID_发布时间
author_id = data["作者ID"]
work_id = data["作品ID"]
publish_time = data["发布时间"].strftime("%Y%m%d_%H%M%S")
return f"{author_id}_{work_id}_{publish_time}"
# 使用自定义命名规则
async with CustomXHS() as xhs:
await xhs.extract(url, download=True)
批量处理扩展
实现批量处理功能扩展:
from typing import List
from source import XHS
class BatchProcessor:
def __init__(self, xhs_instance):
self.xhs = xhs_instance
async def process_batch(self, urls: List[str], batch_size: int = 5):
"""批量处理作品链接"""
results = []
for i in range(0, len(urls), batch_size):
batch = urls[i:i + batch_size]
batch_results = []
for url in batch:
result = await self.xhs.extract(url, download=True)
batch_results.append(result)
results.extend(batch_results)
print(f"已完成批次 {i//batch_size + 1}")
return results
# 使用批量处理器
async with XHS() as xhs:
processor = BatchProcessor(xhs)
urls = ["url1", "url2", "url3", ...] # 作品链接列表
results = await processor.process_batch(urls, batch_size=3)
配置管理最佳实践
1. 环境特定的配置
import os
from source import XHS
def get_config():
"""根据环境获取配置"""
env = os.getenv("XHS_ENV", "development")
base_config = {
"work_path": "/data/xhs_downloads",
"timeout": 10,
"max_retry": 3
}
env_configs = {
"development": {
"proxy": None,
"chunk": 1024 * 512,
"record_data": True
},
"production": {
"proxy": "http://proxy.example.com:8080",
"chunk": 1024 * 1024,
"record_data": False,
"download_record": True
}
}
return {**base_config, **env_configs.get(env, {})}
# 使用环境配置
config = get_config()
async with XHS(**config) as xhs:
await xhs.extract(url, download=True)
2. 配置文件管理
import json
from pathlib import Path
from source import XHS
class ConfigManager:
def __init__(self, config_path="xhs_config.json"):
self.config_path = Path(config_path)
self.config = self.load_config()
def load_config(self):
if self.config_path.exists():
with open(self.config_path, 'r', encoding='utf-8') as f:
return json.load(f)
return self.default_config()
def default_config(self):
return {
"work_path": str(Path.home() / "XHS_Downloads"),
"folder_name": "Download",
"image_format": "WEBP",
"timeout": 8,
"max_retry": 3,
"author_archive": True
}
def save_config(self, config):
with open(self.config_path, 'w', encoding='utf-8') as f:
json.dump(config, f, ensure_ascii=False, indent=2)
# 使用配置管理器
config_manager = ConfigManager()
async with XHS(**config_manager.config) as xhs:
await xhs.extract(url, download=True)
错误处理与日志记录
自定义错误处理
import logging
from source import XHS
class ErrorHandlingXHS(XHS):
async def extract(self, url, download=False, index=None, log=None, bar=None, data=True):
try:
return await super().extract(url, download, index, log, bar, data)
except Exception as e:
logging.error(f"提取作品失败: {url}, 错误: {e}")
# 自定义错误处理逻辑
await self.handle_extract_error(url, e)
return []
async def handle_extract_error(self, url, error):
"""自定义错误处理方法"""
# 记录错误到文件或数据库
# 发送错误通知
# 重试逻辑等
pass
# 使用带错误处理的XHS实例
async with ErrorHandlingXHS() as xhs:
results = await xhs.extract(url, download=True)
性能优化配置
连接池和缓存配置
from source import XHS
import aiohttp
class OptimizedXHS(XHS):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 自定义连接池配置
self.session = aiohttp.ClientSession(
connector=aiohttp.TCPConnector(limit=10, limit_per_host=2),
timeout=aiohttp.ClientTimeout(total=30)
)
async def __aexit__(self, exc_type, exc_value, traceback):
await super().__aexit__(exc_type, exc_value, traceback)
await self.session.close()
# 使用优化配置
async with OptimizedXHS(
timeout=15,
max_retry=2,
chunk=1024*1024*5 # 5MB chunks
) as xhs:
await xhs.extract(url, download=True)
通过以上各种配置和扩展方法,开发者可以根据具体需求对 XHS-Downloader 进行深度定制,实现各种复杂的下载场景和处理逻辑。项目的模块化设计和丰富的配置选项为二次开发提供了极大的灵活性。
用户脚本Tampermonkey集成
XHS-Downloader 提供了强大的 Tampermonkey 用户脚本功能,让用户能够直接在浏览器中提取小红书作品链接并下载无水印文件。该脚本与主程序深度集成,实现了无缝的网页端操作体验。
脚本功能概述
XHS-Downloader 用户脚本提供了以下核心功能:
| 功能类型 | 具体功能 | 支持页面 |
|---|---|---|
| 作品下载 | 下载无水印图文/视频作品 | 作品详情页 |
| 链接提取 | 提取推荐页面作品链接 | 发现页 |
| 账号采集 | 提取发布/收藏/点赞/专辑作品 | 用户主页 |
| 搜索功能 | 提取搜索结果作品/用户链接 | 搜索结果页 |
脚本安装与配置
安装步骤
-
首先确保浏览器已安装 Tampermonkey 扩展
-
访问 XHS-Downloader 项目的脚本链接:
- Master 分支:
https://raw.githubusercontent.com/JoeanAmier/XHS-Downloader/master/static/XHS-Downloader.js - 最新版本:
https://raw.githubusercontent.com/JoeanAmier/XHS-Downloader/refs/heads/master/static/XHS-Downloader.js
- Master 分支:
-
Tampermonkey 会自动检测并提示安装
配置选项
脚本提供了丰富的配置选项,用户可以通过 Tampermonkey 的菜单命令进行设置:
let config = {
packageDownloadFiles: true, // 是否打包下载多个文件
autoScrollSwitch: false, // 自动滚动页面开关
maxScrollCount: 50, // 最大滚动次数
keepMenuVisible: false, // 保持菜单可见
linkCheckboxSwitch: true, // 链接复选框开关
imageCheckboxSwitch: true // 图片复选框开关
};
脚本核心实现机制
作品链接提取算法
无水印文件生成原理
脚本通过解析小红书页面中的数据结构,提取原始媒体文件链接:
// 视频链接生成函数
const generateVideoUrl = note => {
try {
return [`https://sns-video-bd.xhscdn.com/${note.video.consumer.originVideoKey}`];
} catch (error) {
console.error("Error generating video URL:", error);
return [];
}
};
// 图片链接生成函数
const generateImageUrl = note => {
let images = note.imageList;
const regex = /http:\/\/sns-webpic-qc\.xhscdn.com\/\d+\/[0-9a-z]+\/(\S+)!/;
let urls = [];
try {
images.forEach((item) => {
let match = item.urlDefault.match(regex);
if (match && match[1]) {
urls.push(`https://ci.xiaohongshu.com/${match[1]}?imageView2/format/png`);
}
})
return urls
} catch (error) {
console.error("Error generating image URLs:", error);
return [];
}
};
与主程序的深度集成
数据交换格式
脚本提取的作品数据与主程序使用相同的 JSON 格式,确保无缝对接:
{
"type": "normal",
"id": "作品ID",
"title": "作品标题",
"desc": "作品描述",
"user": {
"id": "用户ID",
"nickname": "用户昵称"
},
"time": "发布时间戳",
"imageList": [
{
"urlDefault": "预览图链接",
"url": "原图链接"
}
],
"video": {
"consumer": {
"originVideoKey": "原始视频key"
}
}
}
批量处理流程
高级功能特性
智能文件命名
脚本支持自定义文件命名格式,确保下载的文件组织有序:
// 文件命名配置选项
const fileNameFormats = {
"发布时间 作者昵称 作品标题": "{time} {author} {title}",
"作品标题 作者昵称": "{title} {author}",
"作者昵称 作品ID": "{author} {id}"
};
// 提取作品信息用于文件名
const extractName = () => {
const note = extractNoteInfo();
if (note && note.note) {
const { title, user, time } = note.note;
return `${formatTime(time)} ${user.nickname} ${title}`;
}
return "unknown";
};
选择性下载机制
对于包含多张图片的图文作品,脚本提供了图片选择功能:
// 图片选择模态框
const showImageSelectionModal = (items, name) => {
// 创建复选框列表供用户选择要下载的图片
items.forEach((item, index) => {
createCheckbox(item, index, name);
});
};
// 下载选中的图片
const downloadSelectedImages = (selectedItems, name) => {
selectedItems.forEach(item => {
downloadImage(item.url, `${name}_${item.index}`);
});
};
安全与稳定性保障
错误处理机制
脚本实现了完善的错误处理系统,确保在各种异常情况下都能提供友好的用户反馈:
const abnormal = (text) => {
showTextModal({
title: '发生异常',
text: `${text}请向作者反馈!`,
mode: 'info',
closeText: '关闭'
});
};
const runTips = (text) => {
showTextModal({
title: '脚本提示',
text: text,
mode: 'info',
closeText: '关闭'
});
};
性能优化策略
为了避免对小红书服务器造成过大压力,脚本实现了以下优化措施:
- 请求频率控制:自动添加请求间隔,避免频繁请求
- 滚动加载优化:智能判断页面加载状态,避免无限滚动
- 内存管理:及时清理临时数据,防止内存泄漏
- 超时处理:设置合理的超时时间,避免长时间等待
使用注意事项
- 下载时间:无水印文件处理需要时间,请耐心等待,不要多次点击
- 页面跳转:下载过程中避免页面跳转,否则可能导致下载失败
- 自动滚动:该功能默认关闭,启用可能触发平台风控机制
- 代理设置:使用全局代理可能导致下载失败,必要时请关闭代理
通过 Tampermonkey 用户脚本,XHS-Downloader 实现了网页端与桌面端的完美结合,为用户提供了更加便捷的小红书内容采集体验。脚本的模块化设计和丰富的配置选项,使其能够适应各种使用场景和需求。
批量处理与自动化脚本编写
XHS-Downloader提供了强大的批量处理和自动化能力,通过灵活的API接口和丰富的配置选项,开发者可以轻松构建高效的小红书作品采集流水线。本节将深入探讨如何利用项目特性实现批量下载、自动化处理和脚本集成。
批量链接处理机制
XHS-Downloader内置了智能的批量链接处理功能,支持一次性输入多个作品链接进行批量处理。系统会自动提取有效链接并进行去重处理,确保高效的数据采集。
# 批量处理示例代码
async def batch_process_example():
"""批量处理多个小红书作品链接"""
links = [
"https://www.xiaohongshu.com/explore/1234567890",
"https://xhslink.com/ABCDEFG",
"https://www.xiaohongshu.com/discovery/item/9876543210"
]
async with XHS(
work_path="./downloads",
folder_name="BatchDownload",
download_record=True,
author_archive=True
) as xhs:
results = []
for link in links:
try:
result = await xhs.extract(link, download=True)
results.append(result)
print(f"成功处理: {link}")
except Exception as e:
print(f"处理失败 {link}: {e}")
return results
自动化脚本架构设计
构建自动化脚本时,建议采用模块化的架构设计,将功能分解为独立的组件:
并发处理与性能优化
XHS-Downloader支持异步并发处理,通过合理的并发控制可以显著提升批量处理效率:
import asyncio
from typing import List
from source import XHS
class BatchProcessor:
def __init__(self, max_concurrent=5):
self.max_concurrent = max_concurrent
self.semaphore = asyncio.Semaphore(max_concurrent)
async def process_single(self, xhs: XHS, url: str):
"""处理单个链接"""
async with self.semaphore:
try:
result = await xhs.extract(url, download=True)
return {"url": url, "success": True, "data": result}
except Exception as e:
return {"url": url, "success": False, "error": str(e)}
async def process_batch(self, urls: List[str]):
"""批量处理链接列表"""
async with XHS(
chunk=1024*1024*5, # 5MB块大小
max_retry=3, # 最大重试次数
timeout=30 # 超时时间
) as xhs:
tasks = [self.process_single(xhs, url) for url in urls]
results = await asyncio.gather(*tasks, return_exceptions=True)
# 结果统计与分析
success_count = sum(1 for r in results if isinstance(r, dict) and r.get("success"))
return {
"total": len(urls),
"success": success_count,
"failed": len(urls) - success_count,
"results": results
}
# 使用示例
async def main():
processor = BatchProcessor(max_concurrent=3)
urls = ["https://xhslink.com/ABC123", "https://xhslink.com/DEF456"]
result = await processor.process_batch(urls)
print(f"处理完成: {result['success']}/{result['total']} 成功")
配置文件驱动的自动化
通过外部配置文件驱动自动化流程,实现灵活的批量处理策略:
import json
import yaml
from pathlib import Path
class ConfigDrivenProcessor:
def __init__(self, config_path: str):
self.config = self.load_config(config_path)
def load_config(self, path: str):
"""加载配置文件"""
config_file = Path(path)
if config_file.suffix == '.json':
return json.loads(config_file.read_text())
elif config_file.suffix in ['.yaml', '.yml']:
return yaml.safe_load(config_file.read_text())
else:
raise ValueError("不支持的配置文件格式")
async def execute_workflow(self):
"""执行配置的工作流程"""
config = self.config
async with XHS(
work_path=config.get("work_path", "./downloads"),
folder_name=config.get("folder_name", "BatchDownload"),
**config.get("xhs_config", {})
) as xhs:
# 处理批量链接
for batch in config.get("batches", []):
await self.process_batch(xhs, batch)
async def process_batch(self, xhs: XHS, batch_config: dict):
"""处理单个批配置"""
urls = batch_config.get("urls", [])
options = batch_config.get("options", {})
for url in urls:
result = await xhs.extract(
url,
download=options.get("download", True),
index=options.get("index", None)
)
# 后续处理逻辑...
错误处理与重试机制
健壮的批量处理脚本需要完善的错误处理和重试机制:
import logging
from tenacity import retry, stop_after_attempt, wait_exponential
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class RobustProcessor:
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10),
retry_error_callback=lambda retry_state: False
)
async def robust_extract(self, xhs: XHS, url: str, attempt: int = 1):
"""带重试机制的作品提取"""
try:
result = await xhs.extract(url, download=True)
logger.info(f"成功提取: {url} (尝试次数: {attempt})")
return result
except Exception as e:
logger.warning(f"提取失败 {url} (尝试 {attempt}): {e}")
raise # 触发重试
async def process_with_retry(self, urls: List[str]):
"""带重试的批量处理"""
async with XHS() as xhs:
results = []
for url in urls:
try:
result = await self.robust_extract(xhs, url)
results.append({"url": url, "status": "success", "data": result})
except Exception as e:
results.append({"url": url, "status": "failed", "error": str(e)})
return results
监控与日志系统
完善的监控和日志系统对于自动化脚本至关重要:
import time
from datetime import datetime
from rich.console import Console
from rich.table import Table
class MonitoringSystem:
def __init__(self):
self.console = Console()
self.start_time = time.time()
self.processed_count = 0
self.success_count = 0
def log_progress(self, url: str, success: bool, details: dict = None):
"""记录处理进度"""
self.processed_count += 1
if success:
self.success_count += 1
elapsed = time.time() - self.start_time
status = "✅" if success else "❌"
self.console.print(
f"{status} [{elapsed:.1f}s] 处理 {self.processed_count}: {url}"
)
def generate_report(self):
"""生成处理报告"""
table = Table(title="批量处理报告")
table.add_column("指标", style="cyan")
table.add_column("数值", style="magenta")
table.add_row("总处理数量", str(self.processed_count))
table.add_row("成功数量", str(self.success_count))
table.add_row("失败数量", str(self.processed_count - self.success_count))
table.add_row("成功率", f"{(self.success_count/self.processed_count*100):.1f}%")
table.add_row("总耗时", f"{time.time() - self.start_time:.1f}秒")
self.console.print(table)
# 集成监控的处理器
class MonitoredProcessor:
def __init__(self):
self.monitor = MonitoringSystem()
async def process_with_monitoring(self, urls: List[str]):
"""带监控的批量处理"""
async with XHS() as xhs:
for url in urls:
try:
result = await xhs.extract(url, download=True)
self.monitor.log_progress(url, True, result)
except Exception as e:
self.monitor.log_progress(url, False, {"error": str(e)})
self.monitor.generate_report()
高级批量处理策略表
下表总结了不同的批量处理策略及其适用场景:
| 策略类型 | 并发控制 | 错误处理 | 适用场景 | 性能特点 |
|---|---|---|---|---|
| 顺序处理 | 单线程 | 简单重试 | 小批量数据 | 稳定可靠,速度慢 |
| 并发处理 | 多线程 | 基础重试 | 中等批量 | 平衡性能与稳定性 |
| 异步并发 | 协程池 | 指数退避 | 大批量数据 | 高性能,资源占用低 |
| 分布式处理 | 多进程 | 完善容错 | 超大规模 | 极高吞吐量,复杂部署 |
通过合理选择处理策略和充分利用XHS-Downloader提供的API接口,开发者可以构建出高效、稳定的小红书作品批量处理系统,满足各种规模的自动化采集需求。
总结
XHS-Downloader提供了完整的二次开发框架,通过灵活的API接口、丰富的配置选项和多种扩展方式,开发者可以构建高效的小红书作品采集系统。项目支持从简单的单作品下载到复杂的大规模批量处理,满足各种业务场景需求。文章详细介绍了核心功能实现原理、错误处理机制、性能优化策略以及自动化脚本编写方法,为开发者提供了全面的技术参考。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



