开发日志251210
date
Dec 10, 2025
slug
开发日志251210
status
Published
tags
计算机
AI
summary
给抖音收尾 然后开始处理小红书
type
Post
抖音广告跳过
这个功能实现起来比较简单
//跳过广告
// 1. 定义“广告特征”与“处理动作”的对应关系
const adRules = [
// 每条规则格式: [识别特征数组, 需要点击的按钮文字]
{ keywords: ['发现抖音朋友', '收到朋友'], button: '拒绝' },
{ keywords: ['新版本内测邀请', '检测到更新'], button: '以后再说' },
{ keywords: ['青少年模式', '青少年'], button: '我知道了' },
{ keywords: ['未成年人模式', '未成年'], button: '关闭' },
{ keywords: ['上滑继续看视频'], button: '残忍拒绝' }
];
// 2. 统一的广告监控与处理主循环
threads.start(function () {
for (let round = 1; round <= 5; round++) {
let handled = false; // 标记本轮是否处理了弹窗
// 遍历所有规则
for (let rule of adRules) {
for (let keyword of rule.keywords) {
// 如果屏幕上有符合这个规则的文字
if (text(keyword).exists() || textContains(keyword).exists()) {
logInfo.i(`发现弹窗: ${keyword},尝试点击: ${rule.button}`);
if (clickByText(rule.button)) {
handled = true;
sleepRand(1000, 1500);
break; // 跳出当前规则的关键词循环
}
}
}
if (handled) {
break; // 如果已处理一个弹窗,跳出规则遍历,进入下一轮监控
}
}
sleepRand(1000, 1500);
}
});
// 3. 工具函数:通过按钮文字点击 (与之前相同)
function clickByText(buttonText) {
var btn = text(buttonText).findOne(1000);
if (btn) {
btn.click();
sleepRand(200, 500);
return true;
}
toastLog(`未找到按钮: ${buttonText}`);
return false;
}
全部停止功能修复
这个也比较简单 昨天忘记修改这段代码了 直接获取
taskStatus 用 forEach() 方法处理即可小红书
今天开始小红书环节 刚刚注册好一系列账号 现在考虑如何取做小红书脚本
首先小红书主体是信息流


信息流中有视频内容和帖子内容 进入帖子后内容类似抖音图片 视频则类似抖音视频 有点赞 评论等控件 评论操作也与抖音类似
但是 需要注意的是 由于信息流的存在 导致 执行一次行为 的链条会比较复杂
例如刷视频状态 需要通过 任意方法进入某视频 然后 才能进行类似抖音的刷视频流程 同时刷完视频后应该 返回初始页面 以保证流程:
graph LR
A[信息流界面] -->D{前处理环节}--> B[视频流界面] --执行刷视频/评论-->B-->E{后处理环节}--需要返回信息流-->A
E--不需要返回信息流-->B
A--执行帖子评论-->A
D-->C[发视频界面]--执行发视频-->C-->E
然而抖音也需要这种处理 但是抖音脚本部分只做了执行任务的功能
抖音方面也同理
graph LR
A[通用视频界面] -->D{前处理环节}--> B[同城视频流界面] --执行刷视频/评论-->B-->E{后处理环节}--需要返回推荐页-->A
E--不需要返回-->B
A--执行刷视频/评论-->A
D-->C[发视频界面]--执行发视频-->C-->E此外还要调整一下文件结构 这才写多少就开始堆屎山了 └├─├
原先的结构是:
index.html
utils/ #功能组件
└─taskRunner.js #任务执行器
functions/ #任务脚本
├─tiktok-browse.js #抖音看视频脚本
├─tiktok-comment.js #抖音评论脚本
├─xiaohongshu-browse.js #小红书刷xx脚本
└─common.js #通用函数脚本
platform/ #平台脚本选择器
├─douyin.js #抖音
└─xiaohongshu.js #小红书
如果要加前后处理就不能放在所有任务脚本一起了 只能 按平台分开放
需要分离 跳过广告 , 进入指定页面 , 执行搜索 等功能作为前处理依次执行 返回一个前处理结果 然后再根据前处理结果执行 主要脚本 并返回整个执行结果
需要注意的是 前处理结果可以 预识别视频内容 读取视频作者和标题,并判断本次是否需要点赞/评论 当需要时调用的 主要脚本 仅执行一次当前行为 并不做多余的判断 例如前处理获得视频作者和标题后 判断需要点赞 则调用 点赞脚本 只进行一次点赞操作 如果点赞成功则返回成功 否则失败 评论同理 不在脚本内处理概率判断
那么评中评呢 以及 评论点赞 呢
问了下ai 保存下结果 明天研究
DS
你遇到的困境非常经典,本质是在“原子操作”和“复合任务”之间寻找灵活的编排层。问题的核心是:前处理层需要动态判断接下来要执行哪个(或哪几个)原子脚本,而不是固定搭配。
🔧 解决方案:设计一个“上下文感知”的动态任务编排器
你需要一个智能路由器,它能根据前处理产生的
上下文(Context),动态决定后续的执行链。这个“上下文”里就包含了“是否需要点赞”、“是否需要评论”、“评论给谁”等关键决策。第一步:定义标准的上下文对象
让所有前处理脚本和原子脚本,都接收和返回一个标准化的
上下文对象,作为信息传递的载体。// 定义任务执行的上下文模型
const taskContext = {
// 由前处理脚本填充
currentPage: 'search_result', // 当前所在页面:'home'(推荐流)、'city'(同城)、'search'(搜索结果)、'video_detail'(视频页)
targetVideo: {
id: 'video_123',
author: '某作者',
title: '某标题',
// 前处理脚本可以通过图像识别/OCR将信息提取到这里
},
targetComment: {
id: 'comment_456',
author: '某用户',
content: '这条评论很好',
// 如果需要评论互动,这里就是目标
},
// 决策结果
decisions: {
needLikeVideo: true, // 是否需要给视频点赞
needCommentVideo: true, // 是否需要评论视频
commentTemplate: '好评模板1', // 使用哪个评论模板
needLikeComment: true, // 是否需要给评论点赞
needReplyComment: false // 是否需要回复评论
},
// 执行结果
results: {
likeVideoSuccess: false,
commentVideoSuccess: false,
likeCommentSuccess: false
}
};
第二步:创建可插拔的“决策器” (Decision Maker)
将概率判断和条件判断从脚本中彻底抽离,形成独立的决策模块。决策器读取
上下文,并输出更新了decisions字段的上下文。// deciders/ 目录 - 存放各种决策器
// deciders/videoActionDecider.js
export function decideVideoActions(context) {
const decisions = context.decisions;
// 示例:基于视频作者或标题的复杂规则
if (context.targetVideo.author.includes('广告')) {
decisions.needLikeVideo = false;
decisions.needCommentVideo = false;
} else {
decisions.needLikeVideo = Math.random() < 0.7; // 70%概率点赞
decisions.needCommentVideo = Math.random() < 0.3; // 30%概率评论
}
return context; // 返回更新了decisions的上下文
}
// deciders/commentActionDecider.js
export function decideCommentActions(context) {
const decisions = context.decisions;
// 示例:给热门评论点赞
if (context.targetComment && context.targetComment.likes > 100) {
decisions.needLikeComment = true;
}
return context;
}
第三步:改造前处理脚本为“场景构建器”
前处理脚本的职责变为:1. 跳转到指定场景;2. 为
上下文填充初始数据。// preprocessors/searchAndSelectProcessor.js
export async function process(context, device) {
// 1. 执行一系列前置动作
await openApp(device);
await skipAd(device);
await goToSearchPage(device);
await inputKeyword(device, '目标关键词');
// 2. 识别并选取第一个视频,提取信息
const firstVideoInfo = await identifyFirstVideo(device);
// 3. 更新上下文
context.currentPage = 'search_result';
context.targetVideo = firstVideoInfo;
// decisions 留空,交给决策器
console.log(`[前处理] 已进入搜索页,选中视频:${firstVideoInfo.title}`);
return context; // 返回构建好的上下文
}
第四步:原子脚本保持纯粹
原子脚本只做一件事,并从
上下文中获取指令。// functions/douyin_like_video.js
export async function execute(context, device) {
// 只负责点赞,不判断该不该点
const result = await likeTheCurrentVideo(device);
context.results.likeVideoSuccess = result;
return context;
}
第五步:核心编排引擎
这是大脑,负责按顺序串联:场景构建 -> 决策 -> 执行。
// orchestrators/ 目录 - 核心编排引擎
// orchestrators/mainOrchestrator.js
import { process as searchAndSelect } from '../preprocessors/searchAndSelectProcessor.js';
import { decideVideoActions } from '../deciders/videoActionDecider.js';
import { decideCommentActions } from '../deciders/commentActionDecider.js';
import { execute as likeVideo } from '../functions/douyin_like_video.js';
import { execute as commentVideo } from '../functions/douyin_comment_video.js';
import { execute as likeComment } from '../functions/douyin_like_comment.js';
export async function runDynamicTask(device, taskConfig) {
// 1. 初始化上下文
let context = { currentPage: '', targetVideo: null, decisions: {}, results: {} };
// 2. 【场景构建】根据任务类型,选择不同的前处理器
if (taskConfig.type === 'SEARCH_AND_INTERACT') {
context = await searchAndSelect(context, device);
} else if (taskConfig.type === 'HOMEPAGE_BROWSE') {
context = await anotherPreprocessor(context, device);
}
// 3. 【决策】运行一系列决策器,决定做什么
context = decideVideoActions(context);
context = decideCommentActions(context);
// 4. 【动态执行】根据决策结果,动态调用原子脚本
if (context.decisions.needLikeVideo) {
context = await likeVideo(context, device);
}
if (context.decisions.needCommentVideo) {
context = await commentVideo(context, device);
}
if (context.targetComment && context.decisions.needLikeComment) {
context = await likeComment(context, device);
}
// 5. 返回完整的执行结果上下文
console.log('任务完成,最终结果:', context.results);
return context;
}
📁 最终的优化目录结构
你的项目根目录
├── index.html
├── main.js # 系统入口
├── utils/taskRunner.js # 基础执行器(可能被调用)
├── orchestrators/ # 【新增】核心编排层
│ └── mainOrchestrator.js # 动态任务大脑
├── preprocessors/ # 【场景构建层】
│ ├── searchAndSelectProcessor.js
│ ├── homepageProcessor.js
│ └── cityPageProcessor.js
├── deciders/ # 【决策层】
│ ├── videoActionDecider.js
│ └── commentActionDecider.js
├── functions/ # 【原子操作层】保持纯净
│ ├── douyin_like_video.js
│ ├── douyin_comment_video.js
│ ├── douyin_like_comment.js
│ └── ...
└── platform/ # 【平台适配层】调用编排器
├── douyin.js # 调用 orchestrators/mainOrchestrator.runDynamicTask(...)
└── xiaohongshu.js
💡 这个模式如何解决你的问题?
- 前处理复用:
searchAndSelectProcessor.js这样的前处理脚本,可以为“搜索后刷视频”、“搜索后评论”等多种后续任务提供统一的场景构建服务,无需重复编写。
- 动态决策链:通过独立的
决策器,你可以组合出无限可能:“给视频点赞” -> “给视频评论” -> “给这个评论点赞” -> “再回复一条”。只需按顺序调用对应的决策器和原子脚本。
- 原子脚本极致纯粹:每个脚本只做一件小事(点赞、评论),不包含任何“是否应该做”的判断逻辑。判断逻辑全部上移到可配置、可复用的决策器中。
总结:你不需要为每种组合写一个前处理,而是需要:
- 写不同的“场景构建器”(前处理)来进入不同页面。
- 写不同的“决策器” 来定义在不同场景下做什么动作的组合与概率。
- 写一个“编排引擎” 来把1和2,以及纯粹的原子脚本,像搭积木一样组合起来。
这样,当你想增加“给评论的评论点赞”这个新行为时,你只需要:1)写一个
decideReplyToCommentDecider.js 决策器;2) 确保有一个能获取到targetComment上下文的前处理器;3)在编排引擎中按需调用它。完全不需要改动任何原子脚本或重写前处理。Grok
问题分析与整体思路
你当前的痛点很清楚:原脚本是“简单线性流程”(刷视频 → 概率点赞/评论),但现在需要支持更复杂的场景(如进入同城页、搜索特定视频),并且要分离“前处理”(pre-processing,如跳过广告、导航页面、预识别视频)和“主要脚本”(core actions,如点赞、评论)。关键挑战是:
- 前处理需要“智能判断”(e.g., 基于视频作者/标题决定是否点赞/评论),但主要脚本要保持“哑巴”(只执行一次动作,不带判断)。
- 如果引入概率(e.g., 评论后概率点赞)或组合(e.g., 点赞 + 评论评论),前处理就容易爆炸:每种组合都需要自定义前处理,导致代码重复和维护噩梦。
我的建议:采用“配置驱动的任务管道(Pipeline)”架构。核心思想:
- 统一前处理层:所有任务共享一个前处理管道(pipeline),这是一个函数数组,按序执行(e.g., 跳过广告 → 进入页面 → 搜索 → 预识别视频)。
- 规则引擎:在前处理末尾,用一个“决策器”(decider)基于配置规则(e.g., 概率、条件)动态生成“动作列表”(actions list),如 [点赞, 评论, 评论后点赞]。
- 主要脚本:只是一个“执行器”(executor),接收动作列表,按序调用独立的“原子动作函数”(e.g., likeVideo() 只点赞一次,不带任何判断)。
- 整个流程:前处理返回 { success: true, videoInfo: {...}, actionsToRun: [...] },然后主要执行器跑 actionsToRun,返回 { preResult, mainResult }。
优点:
- 灵活组合:不用为每种情况写新前处理,只改配置(e.g., JSON 对象)就能实现“评论后概率点赞”或“给评论评论”。
- 解耦:原子动作函数保持纯净(只做一件事),判断全在前处理决策器里。
- 可扩展:以后加新前处理(如“检查网络”)或新动作(如“转发”)只需加函数到管道/列表。
- 整个结果:返回包含前处理 + 主要执行的完整日志/结果,便于群控系统监控。
缺点:初始配置稍复杂,但远胜于写 N 个自定义脚本。
推荐架构设计
1. 核心组件定义
- 前处理管道 (prePipeline):一个函数数组,每个函数返回 { success: bool, data: {...} } 或抛错。失败时中断管道。
- 示例函数:skipAd(), enterPage('同城'), searchVideo('关键词'), recognizeVideo()。
- 决策器 (decider):在前处理数据基础上,用规则生成 actions 列表。
- 规则用 JSON 配置:支持条件 (if author == 'xxx' then like)、概率 (random 30% then comment)、序列 (after comment then 50% like)。
- 原子动作 (atomicActions):独立的函数,只执行一次行为,返回 { success: bool, msg: '...' }。
- e.g., likeVideo(), commentVideo('内容'), replyToComment('回复')。
- 主要执行器 (mainExecutor):接收 actions 列表,按序执行,返回结果数组。
- 配置对象 (taskConfig):JSON 驱动整个任务,定义管道、规则等。
2. 示例配置 JSON
每个任务一个 config 对象(可从文件/数据库加载):
{
"taskName": "搜索视频后概率点赞+评论",
"prePipeline": [
"skipAd", // 函数名或引用
"enterPage:sameCity", // 支持参数
"searchVideo:门窗广告", // 支持参数
"recognizeVideo" // 预识别作者/标题
],
"decisionRules": [
{
"if": "video.author.includes('品牌X')", // 条件 (JS 表达式)
"then": [
{ "action": "likeVideo", "prob": 0.8 }, // 80% 概率点赞
{ "action": "commentVideo", "prob": 0.5, "args": "好产品!" }, // 50% 概率评论
{ "after": "commentVideo", "action": "likeComment", "prob": 0.3 } // 评论后 30% 概率点赞评论
]
},
{
"if": "true", // 默认规则
"then": [{ "action": "likeVideo", "prob": 0.3 }] // 低概率默认点赞
}
],
"postPipeline": [] // 可选后处理,如“返回推荐页”
}
3. 核心代码实现(Auto.js / JS 示例)
假设你的群控系统用 JS,这里给一个简化版实现(可直接复制到你的脚本)。
// ==================== 原子动作函数(保持纯净,只执行一次) ====================
function skipAd() {
// 模拟:点击跳过广告
if (id("skip_ad").exists()) {
id("skip_ad").findOne().click();
return { success: true, data: {} };
}
return { success: false, msg: "无广告" };
}
function enterPage(pageType) {
// 模拟:进入同城/搜索页
if (pageType === 'sameCity') {
id("same_city_btn").click();
} // ... 其他类型
sleep(1000);
return { success: true, data: { page: pageType } };
}
function searchVideo(keyword) {
// 模拟:输入搜索 + 确认
id("search_input").setText(keyword);
id("search_btn").click();
sleep(2000);
return { success: true, data: { keyword } };
}
function recognizeVideo() {
// 模拟:OCR 或 UI 识别作者/标题
const author = textContains("@").findOne()?.text() || "";
const title = descContains("视频标题").findOne()?.desc() || "";
return { success: true, data: { author, title } };
}
function likeVideo() {
// 只点赞一次
if (id("like_btn").exists()) {
id("like_btn").findOne().click();
return { success: true, msg: "点赞成功" };
}
return { success: false, msg: "点赞失败" };
}
function commentVideo(content) {
// 只评论一次
id("comment_input").setText(content);
id("send_comment").click();
return { success: true, msg: "评论成功" };
}
function likeComment() {
// 只点赞最新评论
if (className("CommentLikeBtn").exists()) {
className("CommentLikeBtn").findOne().click();
return { success: true, msg: "点赞评论成功" };
}
return { success: false, msg: "无评论可点赞" };
}
// ==================== 函数映射(易扩展) ====================
const funcMap = {
skipAd, enterPage, searchVideo, recognizeVideo,
likeVideo, commentVideo, likeComment
// 加新函数在这里
};
// ==================== 决策器(生成 actions 列表) ====================
function decideActions(videoInfo, rules) {
const actions = [];
for (let rule of rules) {
if (eval(rule.if)) { // 安全起见,可用 new Function() 代替 eval
for (let act of rule.then) {
if (Math.random() < (act.prob || 1)) {
actions.push(act);
}
}
break; // 第一匹配规则生效
}
}
return actions; // e.g., [{action: "likeVideo"}, {action: "commentVideo", args: "..."}]
}
// ==================== 主要执行器 ====================
function runMain(actions) {
const results = [];
let lastAction = null;
for (let act of actions) {
// 处理 "after" 依赖
if (act.after && act.after !== lastAction?.action) continue;
const func = funcMap[act.action];
if (func) {
const res = func(act.args);
results.push({ action: act.action, ...res });
lastAction = act;
} else {
results.push({ action: act.action, success: false, msg: "未知动作" });
}
}
return results;
}
// ==================== 完整任务运行器 ====================
function runTask(taskConfig) {
const preResults = [];
let preData = {};
// 执行前处理管道
for (let preStep of taskConfig.prePipeline) {
const [funcName, arg] = preStep.split(':'); // 支持参数
const func = funcMap[funcName];
if (!func) return { success: false, msg: `未知前处理: ${funcName}` };
const res = func(arg?.trim());
preResults.push({ step: funcName, ...res });
if (!res.success) return { success: false, preResults };
Object.assign(preData, res.data); // 累积数据
}
// 决策生成 actions
const actions = decideActions(preData, taskConfig.decisionRules);
// 执行主要脚本
const mainResults = runMain(actions);
// 可选后处理(类似前处理)
return { success: true, preResults, mainResults };
}
// ==================== 示例调用 ====================
const config = { /* 上面的 JSON 示例 */ };
const fullResult = runTask(config);
toastLog(JSON.stringify(fullResult, null, 2)); // 返回整个结果
如何解决你的具体问题
- 概率点赞/评论:全在前处理决策器里用
prob处理,主要脚本不变。
- 评论后概率点赞:用
after: "commentVideo"在规则里定义依赖顺序,主要脚本无需知道。
- 给评论评论:加新原子动作
replyToComment(),在规则里加{action: "replyToComment", after: "commentVideo"}。
- 每种情况不用新前处理:所有任务共享同一管道和决策器,只改 config JSON(e.g., 不同任务有不同 rules)。
- 群控扩展:在群控主控端,用 JSON config 发给每个设备,设备运行
runTask(config)返回结果。
这个架构在实际群控系统(如抖音批量脚本)中超稳,代码量少、复用高。如果你需要更细的 Auto.js UI 适配或完整项目 demo,直接说!