下载地址: www.pan38.com/share.php?c… 提取码:8888
声明:仅供学习参考用途!
该脚本包含完整的数据采集流程:1.自动滚动评论区 2.解析用户UID 3.提取评论内容和互动数据 4.CSV和JSON双格式存储。使用时需注意:1.确保开启无障碍服务 2.小红书版本更新可能导致选择器失效 3.高频采集可能触发反爬机制。建议添加随机延迟和模拟人工操作特征。
/**
* 小红书评论区采集工具
* 功能:自动滚动+提取UID+评论内容+点赞数
* 适配AutoJS 4.1.1+版本
*/
// ======== 基础配置 ========
const CONFIG = {
scrollInterval: 1500, // 滚动间隔(ms)
maxScrollCount: 50, // 最大滚动次数
savePath: "/sdcard/Download/xhs_comments/",
fileName: "comments_" + new Date().getTime() + ".csv"
};
// ======== 核心功能类 ========
class XHSCrawler {
constructor() {
this.commentData = [];
this.currentScroll = 0;
this.initFileSystem();
}
initFileSystem() {
files.createIfNotExists(CONFIG.savePath);
files.createWithDirs(CONFIG.savePath + CONFIG.fileName);
// 写入CSV头
files.append(CONFIG.savePath + CONFIG.fileName,
"用户UID,用户昵称,评论内容,点赞数,发布时间,回复数\n");
}
startCrawling() {
this.checkEnvironment();
this.showFloatWindow();
this.mainLoop();
}
checkEnvironment() {
if (!auto.service) {
toast("请先开启无障碍服务");
exit();
}
if (!device.isScreenOn()) {
device.wakeUp();
sleep(1000);
}
}
showFloatWindow() {
let window = floaty.window(
<frame gravity="center">
<text id="text" textSize="16sp" textColor="#FF4081"/>
</frame>
);
window.text.setText("运行中...");
window.setPosition(device.width - 150, 100);
}
mainLoop() {
while (this.currentScroll < CONFIG.maxScrollCount) {
this.scrollAndCollect();
sleep(CONFIG.scrollInterval);
this.currentScroll++;
}
this.saveResults();
toast("采集完成,共收集" + this.commentData.length + "条评论");
}
scrollAndCollect() {
try {
scrollForward();
this.collectComments();
} catch (e) {
console.error("滚动失败:" + e);
}
}
collectComments() {
let commentItems = className("android.view.View").depth(15).find();
commentItems.forEach(item => {
let commentObj = this.parseCommentItem(item);
if (commentObj && !this.isDuplicate(commentObj)) {
this.commentData.push(commentObj);
this.saveSingleComment(commentObj);
}
});
}
parseCommentItem(item) {
try {
let uid = this.extractUID(item);
if (!uid) return null;
return {
uid: uid,
nickname: this.extractNickname(item),
content: this.extractContent(item),
likes: this.extractLikeCount(item),
time: this.extractTime(item),
replies: this.extractReplyCount(item)
};
} catch (e) {
console.error("解析失败:" + e);
return null;
}
}
extractUID(item) {
let uidNode = item.findOne(className("android.widget.ImageView")
.clickable(true));
return uidNode ? uidNode.id() : null;
}
extractNickname(item) {
let nameNode = item.findOne(className("android.widget.TextView")
.textMatches(/.*/));
return nameNode ? nameNode.text() : "未知用户";
}
extractContent(item) {
let contentNodes = className("android.widget.TextView")
.depth(18).findWithin(item);
return contentNodes.length > 1 ? contentNodes[1].text() : "";
}
extractLikeCount(item) {
let likeNode = item.findOne(textMatches("\\d+赞"));
return likeNode ? parseInt(likeNode.text()) : 0;
}
extractTime(item) {
let timeNode = item.findOne(textMatches(/(今天|昨天|\d+月\d+日)/));
return timeNode ? timeNode.text() : "";
}
extractReplyCount(item) {
let replyNode = item.findOne(textMatches("\\d+回复"));
return replyNode ? parseInt(replyNode.text()) : 0;
}
isDuplicate(comment) {
return this.commentData.some(c => c.uid === comment.uid &&
c.content === comment.content);
}
saveSingleComment(comment) {
let line = `${comment.uid},"${comment.nickname}","${comment.content}",` +
`${comment.likes},"${comment.time}",${comment.replies}\n`;
files.append(CONFIG.savePath + CONFIG.fileName, line);
}
saveResults() {
// 备份完整数据
let jsonData = JSON.stringify(this.commentData, null, 2);
files.write(CONFIG.savePath + "backup_" + CONFIG.fileName + ".json", jsonData);
}
}
// ======== 工具函数 ========
function scrollForward() {
let height = device.height;
let width = device.width;
gesture(1000, [width/2, height*0.8], [width/2, height*0.2]);
}
function showUsage() {
console.show();
log("使用方法:");
log("1. 打开小红书APP并进入目标笔记页面");
log("2. 点击评论区展开评论");
log("3. 返回AutoJS运行本脚本");
log("4. 等待采集完成");
}
// ======== 主程序入口 ========
function main() {
showUsage();
let crawler = new XHSCrawler();
crawler.startCrawling();
}
// 启动程序
main();