采集小红书评论区用户UID,提取小红书评论内容,最新AUTOJS脚本

2 阅读1分钟

下载地址: 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();