菜单

Administrator
发布于 2025-06-03 / 135 阅读
0
0

一个自动刷阅读量的控制台小代码

1、效果和场景

rt,通常对于某些论坛,可能会有一些阅读要求,比如需要阅读量大于多少。

这个代码的作用就是会自动向下滑动页面,模拟鼠标向下滚动。

并且会自动触发翻页动作

2、代码

// 带有定时暂停功能的智能滚动
function smartScrollWithPauses() {
  const viewportHeight = window.innerHeight;
  let documentHeight = Math.max(
    document.body.scrollHeight,
    document.documentElement.scrollHeight
  );
  let currentPosition = window.pageYOffset || document.documentElement.scrollTop;
  const smallStep = 10;
  const smallStepInterval = 10000 / (viewportHeight / smallStep);
  let bottomDetectionCount = 0;
  const maxBottomDetections = 3;
  let lastDocumentHeight = documentHeight;
  let noNewContentCount = 0;
  const maxNoNewContent = 5;
  let isTabActive = !document.hidden;
  let isPaused = false;
  
  // 滚动计时器
  let scrollTimer = 0;
  // 3-5分钟后暂停(转为毫秒)
  const scrollDuration = (3 * 60 + Math.floor(Math.random() * 2 * 60)) * 1000;
  // 暂停1分钟(毫秒)
  const pauseDuration = 60 * 1000;
  
  console.log(`开始智能滚动,视窗高度: ${viewportHeight}px, 文档总高度: ${documentHeight}px`);
  console.log(`将在 ${Math.round(scrollDuration/1000/60)} 分钟后暂停 ${pauseDuration/1000/60} 分钟`);
  
  // 监听页面可见性变化
  document.addEventListener('visibilitychange', () => {
    isTabActive = !document.hidden;
    console.log(`页面可见性变化: ${isTabActive ? '前台' : '后台'}`);
  });
  
  // 定时暂停和恢复功能
  function managePauses() {
    scrollTimer += 1000;
    
    // 检查是否需要暂停
    if (scrollTimer >= scrollDuration && !isPaused) {
      isPaused = true;
      console.log(`已滚动 ${Math.round(scrollTimer/1000/60)} 分钟,开始暂停 ${pauseDuration/1000/60} 分钟`);
      
      // 设置定时器,暂停后恢复
      setTimeout(() => {
        isPaused = false;
        scrollTimer = 0;
        console.log('暂停结束,继续滚动');
        
        // 计算新的滚动持续时间(3-5分钟)
        const newScrollDuration = (3 * 60 + Math.floor(Math.random() * 2 * 60)) * 1000;
        console.log(`将在 ${Math.round(newScrollDuration/1000/60)} 分钟后再次暂停`);
      }, pauseDuration);
    }
    
    // 每秒检查一次
    setTimeout(managePauses, 1000);
  }
  
  function scrollStep() {
    // 如果页面在后台或处于暂停状态,等待条件恢复再继续
    if (!isTabActive || isPaused) {
      const reason = !isTabActive ? '页面在后台' : '处于计划暂停';
      console.log(`暂停滚动: ${reason}`);
      setTimeout(scrollStep, 1000);
      return;
    }
    
    documentHeight = Math.max(
      document.body.scrollHeight,
      document.documentElement.scrollHeight
    );
    
    if (currentPosition + viewportHeight >= documentHeight - 50) {
      bottomDetectionCount++;
      console.log(`到达底部 ${bottomDetectionCount}/${maxBottomDetections}`);
      
      if (bottomDetectionCount >= maxBottomDetections) {
        console.log('尝试触发加载更多内容...');
        
        // 多次滚动到底部,增加触发加载的几率
        for (let i = 0; i < 3; i++) {
          setTimeout(() => {
            window.scrollTo(0, documentHeight + 100);
          }, i * 300);
        }
        
        setTimeout(() => {
          const newDocumentHeight = Math.max(
            document.body.scrollHeight,
            document.documentElement.scrollHeight
          );
          
          if (newDocumentHeight > documentHeight) {
            console.log(`检测到新内容加载,高度从 ${documentHeight}px 增加到 ${newDocumentHeight}px`);
            bottomDetectionCount = 0;
            noNewContentCount = 0;
            lastDocumentHeight = newDocumentHeight;
            scrollStep();
          } else {
            noNewContentCount++;
            console.log(`没有检测到新内容 ${noNewContentCount}/${maxNoNewContent}`);
            
            if (noNewContentCount >= maxNoNewContent) {
              console.log('已确认没有更多内容可加载,停止滚动');
              return;
            }
            
            bottomDetectionCount = 0;
            scrollStep();
          }
        }, 2000);
        
        return;
      }
    } else {
      bottomDetectionCount = 0;
    }
    
    currentPosition += smallStep;
    window.scrollTo(0, currentPosition);
    
    const randomDelay = smallStepInterval * (0.8 + Math.random() * 0.4);
    setTimeout(scrollStep, randomDelay);
  }
  
  // 启动暂停管理
  managePauses();
  // 启动滚动
  scrollStep();
}

// 启动带有定时暂停功能的智能滚动
smartScrollWithPauses();

3、用法

复制代码,到控制台。即可运行

ps:不建议后台运行,建议放在前台。然后去吃饭吧

由于某些论坛会有限速策略,可以自行修改一些速度控制

比如上述的10000 是指下滑速度。

4、新增带有点赞功能,随机点赞

// ==========================================
// 自动浏览 + 目标点赞 (修正选择器版)
// ==========================================

async function startAutoScrollAndTargetLike() {
  // --- 🔧 配置区域 ---
  const config = {
    // 滚动步长
    scrollStepSize: 10,
    
    // 🔥 你的新选择器
    likeSelector: 'div[title="点赞此帖子"]', 
    
    // 点赞概率 (0.3 表示 30% 的几率点赞,避免每个都点导致被封)
    likeProbability: 0.3, 
    
    // 点赞后的动作延迟 (你的逻辑里是2000,为了流畅浏览我设为 1500~2500 随机)
    actionDelayMin: 1500,
    actionDelayMax: 2500,

    // 休息配置 (毫秒)
    scrollDurationBase: 3 * 60 * 1000, // 3分钟后休息
    pauseDuration: 60 * 1000           // 休息1分钟
  };

  // --- 状态变量 ---
  const viewportHeight = window.innerHeight;
  let currentPosition = window.pageYOffset || document.documentElement.scrollTop;
  const smallStepInterval = 10000 / (viewportHeight / config.scrollStepSize);
  
  let bottomDetectionCount = 0;
  let isTabActive = !document.hidden;
  let isPaused = false;
  let scrollTimer = 0;
  let stopScript = false;
  let currentRunDuration = config.scrollDurationBase + Math.floor(Math.random() * 2 * 60 * 1000);

  // 辅助函数:延迟
  const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

  console.log(`%c[启动] 脚本运行中... 目标选择器: ${config.likeSelector}`, "color: green; font-weight: bold");

  // --- 1. 休息管理 (保持不变) ---
  function managePauses() {
    if (stopScript) return;
    scrollTimer += 1000;
    if (scrollTimer >= currentRunDuration && !isPaused) {
      isPaused = true;
      console.log(`%c[休息] 已运行 ${Math.round(scrollTimer/1000/60)} 分钟,休息一会儿...`, "color: orange");
      setTimeout(() => {
        isPaused = false;
        scrollTimer = 0;
        currentRunDuration = config.scrollDurationBase + Math.floor(Math.random() * 60000);
        console.log(`%c[恢复] 继续浏览`, "color: green");
        requestScrollStep();
      }, config.pauseDuration);
    }
    setTimeout(managePauses, 1000);
  }

  document.addEventListener('visibilitychange', () => isTabActive = !document.hidden);

  // --- 2. 点赞核心逻辑 (使用你提供的新逻辑) ---
  async function processLikes() {
    // 获取当前页面所有符合条件的按钮
    const elements = document.querySelectorAll(config.likeSelector);
    
    for (const el of elements) {
      if (stopScript) break;

      // 1. 过滤掉已经处理过的 (防止重复点击同一个)
      if (el.classList.contains('script_processed')) continue;

      // 2. 检查元素是否在可视区域内 (只点看得到的)
      const rect = el.getBoundingClientRect();
      if (rect.top < 50 || rect.bottom > window.innerHeight - 50) {
        continue; // 不在视野内,跳过
      }

      // 标记已处理 (无论点不点,都标记,避免下次循环卡死在这里)
      el.classList.add('script_processed');

      // 3. 随机判定是否点赞
      if (Math.random() > config.likeProbability) {
        // 随机决定放过这个帖子
        continue;
      }

      // --- 执行你的点赞逻辑 ---
      console.log(`%c[点赞] 发现目标,执行点击`, "color: magenta");
      
      // A. 点击
      el.click();
      
      // B. 滚动聚焦 (你要求的逻辑)
      el.scrollIntoView({ behavior: 'smooth', block: 'center' });
      
      // C. 等待 (模拟你的 setTimeout 2000)
      const waitTime = config.actionDelayMin + Math.random() * (config.actionDelayMax - config.actionDelayMin);
      await delay(waitTime);

      // 为了不卡住浏览,每次循环最多点一个
      return true; 
    }
    return false;
  }

  // --- 3. 滚动主循环 ---
  async function scrollStep() {
    if (stopScript) return;

    // 暂停检查
    if (!isTabActive || isPaused) {
      setTimeout(() => requestScrollStep(), 1000);
      return;
    }

    // A. 先检查有点赞任务没 (优先级最高)
    const didLike = await processLikes();

    // 如果刚才执行了点赞和 scrollIntoView,由于画面已经动了,
    // 我们就不执行这次的常规滚动,直接进入下一次循环,这样更丝滑
    if (didLike) {
      setTimeout(() => requestScrollStep(), 100); 
      return;
    }

    // B. 常规到底部检测与加载 (原来的逻辑)
    let documentHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
    if (currentPosition + viewportHeight >= documentHeight - 50) {
      bottomDetectionCount++;
      if (bottomDetectionCount >= 3) {
        console.log('[加载] 触底,尝试加载新内容...');
        for (let i = 0; i < 3; i++) { 
            window.scrollTo(0, documentHeight + 150); 
            await delay(300); 
        }
        await delay(2000);
        
        const newH = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
        if (newH > documentHeight) {
          console.log('[加载] 成功');
          bottomDetectionCount = 0;
          requestScrollStep();
        } else {
          console.log('%c[结束] 到底了,停止脚本', "color: red");
          stopScript = true;
        }
        return;
      }
    } else {
      bottomDetectionCount = 0;
    }

    // C. 正常滚动
    currentPosition += config.scrollStepSize;
    window.scrollTo(0, currentPosition);

    // 随机间隔
    const randomDelay = smallStepInterval * (0.8 + Math.random() * 0.4);
    setTimeout(() => requestScrollStep(), randomDelay);
  }

  function requestScrollStep() {
    scrollStep().catch(e => console.error(e));
  }

  // 启动
  managePauses();
  requestScrollStep();

  return { stop: () => stopScript = true };
}

// 运行脚本
var autoBrowser = startAutoScrollAndTargetLike();


评论