robotask内新建一个简单采集任务 但以封装思路可复用逻辑来设计

Avatar
Posts 142

robotask内新建一个简单采集任务 但以封装思路可复用逻辑来设计 笔记 2026-07-04 18h50s54

先用36kr 快讯 测试取值

TEXT

document.querySelectorAll(".flow-item")
看看有多少个
document.querySelectorAll(".flow-item")[0]
看看第一个
document.querySelectorAll(".flow-item")[0].innerText

取第一个的标题、链接、日期

TEXT

let item = document.querySelectorAll(".flow-item")[0];
console.log(item.querySelector(".item-title").innerText);
console.log(item.querySelector(".item-title").href);
console.log(item.querySelector(".time").innerText);

完整测试

TEXT

let item = document.querySelectorAll(".flow-item")[0];
let news = {

    title: item.querySelector(".item-title").innerText,

    url: item.querySelector(".item-title").href,

    time: item.querySelector(".time").innerText

};
news;

但出现了错误 Path is empty 这时候需要梳理逻辑

了解 robotask 的Execute JavaScript 逻辑

以下是从官方pdf faq找寻的全部帮助 我们看看是哪里需要调整
执行 JavaScript”操作会在浏览器中运行自定义 JavaScript代码。这个强大的操作让你可以以其他操作可能无法涵盖的方式与页面互动。

从复杂的 JavaScript 渲染页面中提取数据 绕过标准操作的限制(隐藏元素、Shadow DOM) 对页面内容进行计算或数据转换 在截屏前修改页面外观(隐藏横幅、弹窗) 处理特殊情况,如无限滚动或懒加载 访问页面变量或 JavaScript 函数 注意:此操作需要 JavaScript 编程知识。没有编程技能的用户可以使用其他操作完成大多数任务

选择要运行脚本的浏览器
内联脚本类型或直接将 JavaScript 粘贴到文本区域 适合短脚本或快速操作 支持多行代码和完整的 JavaScript 语法

如何返回值 要把结果保存到一个变量,你的脚本必须使用 return 语句
将结果保存到变量 可选:输入一个变量名来存储脚本的返回值 你的脚本必须使用 return 语句来返回值 如果脚本没有返回值,请留空

TEXT


// Get page title
return document.title;
// Count elements
return document.querySelectorAll('.item').length;
// Get multiple values as JSON
return {
    title: document.title,
    url: window.location.href,
    timestamp: new Date().toISOString()
};
Examples of usage. 
Extract data from a table:
const rows = document.querySelectorAll('table tr');
const data = [];
rows.forEach(row => {
    const cells = row.querySelectorAll('td');
    if (cells.length >= 2) {
        data.push({
            name: cells[0].textContent,
            value: cells[1].textContent
        });
    }
});
return JSON.stringify(data);
Scroll to bottom of page:
window.scrollTo(0, document.body.scrollHeight);
// No return needed for actions without results

导致 Path is empty 错误的原因严谨追查

为了搞清楚这个问题 首先我确认本地环境是否异常,所以我在新电脑直接安装官方最新版和对应的ChromiumSetup64(11)插件,直接在里面测试,结果没有意外依然是Path is empty ,
你说的浏览器绑定我最先测试 微软的浏览器和默认的 built-in 均一样返回错误
所以我将目光再次调整,是否是我的用法错了,于是我将直接跑以下官方的示例
我注意到执行js对话框 浏览器下拉默认是Browser1,我改为built-in后无法测试只有默认Browser1才行
点击测试会打开一个浏览器 且可以进行F12调试 应该不存在没有对象可以访问
于是我跑了官方的两个案例和你给的两个 都一样返回错误

TEXT

const item = document.querySelector(".flow-item");
return JSON.stringify({
    title:item.querySelector(".item-title").innerText,

    url:item.querySelector(".item-title").href,

    time:item.querySelector(".time").innerText
});

我现在甚至已经用了最新版 11.0.7.347 不至于bug这么明显吧 如果开发者连基础测试都没通过想必在上个版本就已经否决发布了
没错 这个web自动化插件 的确是 CEF(Chromium Embedded Framework)模式
以下是我调取这两个插件的属性信息:

TEXT


  Description: Embedded Chromium Browser
  Location: D:\Work\RoboTask\Plugins\Chromium\Chromium.rtp
  --------
  Number of Actions: 7
  * Action "Browser Fill Web Form"
  * Action "Browser Web Page Information"
  * Action "Browser Click Link"
  * Action "Browser Wait for Done"
  * Action "Browser Page Snapshot"
  * Action "Browser Window Size"
  * Action "Browser Run Javascript"
  --------
  Number of Triggers: 0


  Description: Web Automation
  Location: D:\Work\RoboTask\Plugins\WebAutomation\WebAutomation.rtp
  --------
  Number of Actions: 11
  * Action "Start Browser"
  * Action "Close Browser"
  * Action "Navigate"
  * Action "Mouse Click / Hover / Focus"
  * Action "Click Download Link"
  * Action "Send Keys"
  * Action "Get Element Property"
  * Action "Get Page Details"
  * Action "Set Form Field Value"
  * Action "Take Screenshot"
  * Action "Execute Javascript"
  --------
  Number of Triggers: 0

再次测试

为了验证你这个问题首先我说明一下,ChromiumSetup64独立包安装后就会安装在C:\RoboTask\CEF\ 体积440M,同时会生成插件
D:\Work\RoboTask\Plugins\Chromium\Chromium.rtp
而D:\Work\RoboTask\Plugins\WebAutomation\WebAutomation.rtp 插件我认为是直接操作了这个浏览器基底,
现在开始验证你的假设,
1.看一下纯Chromium插件内的 Action "Browser Run Javascript" 是否能操作WebAutomation的 Action "Start Browser"
结论是:W: 2026/7/4 16:46:20: CEF未加载 跳过步骤.
2.直接让Chromium.rtp的Action "Browser Fill Web Form" 打开网页再让WebAutomation的 Action "Execute Javascript"执行js,但无法读取浏览器对象所以我输入了CEF,
运行后得到错误E: 2026/7/4 16:52:18: Browser variable "CEF" is empty or not found
所以这两个假设测试失败,目前来看 WebAutomation有独立的体系可以访问内置浏览器,因为我测试了WebAutomation的"Start Browser"打开网页再"Get Page Details"获取标题 成功了

Chromium.rtp 和 WebAutomation.rtp 是两套完全不同的 Browser 对象。

进行temp文件夹监控 测试

首先我测试执行脚本 当打开浏览器后弹出错误 我看到监控根据出现了200多个日志数 首先我看到
C:\RoboTask\Neocore\neocore.exe 启动了一些东西 并创建了一些诸如 临时文件C:\Users\c\AppData\Local\Temp\12d7a267-9352-4edf-9831-985d105e43fc.tmp
当然后面的是由 explorer读取了一些 C:\Users\c\AppData\Local\Temp\playwright_chromiumdev_profile-FHRHc6
但这都不是关键信息,为了看下执行js有没有动静我直接把刚才打开的界面再次点击测试 观察监控 结果无任何反应
既如此我直接把他作为外部js执行试试返回说明错误 随便下载一个js执行

C:\Users\c\Downloads\a.js
这次返回:value result not found
既然做到这一步了 我觉得直接可以测试正确的代码,我直接改为

真正解决问题在这一步 但是每次新建一个任务 使用内部js都会问题依旧,所以这里我们直接就用外部初始化一下一个空文件再执行真正的内部脚本

TEXT

const item = document.querySelector(".flow-item");
return JSON.stringify({

    title:item.querySelector(".item-title").innerText,

    url:item.querySelector(".item-title").href,

    time:item.querySelector(".time").innerText

});

测试后得到弹窗为标题、链接和时间,那说明外部跑通,但内部js难道不是一个逻辑吗?内部不行 同样的代码只有外部行
于是我直接把代码再次粘贴到内部文本框 点击测试,结果返回与上面执行的一样!
这真是无语了,于是我保存关闭又再次试了一次,以及再执行了一次外部模式 都正确返回。
你说说

排查日志

Inline 和 Script File 最终走的是同一套执行器。
这次得出的逻辑结论可能是:

TEXT


第一次运行 ExecuteJavascript
↓

检查 Script Engine
↓

Path=""
↓

报错
↓

切换 Script File
↓

初始化成功
↓
Script Engine Loaded
↓

以后 Inline 也正常

缓存路径目录(C:\Users\c\AppData\Local\Temp\cef\cache)不是根缓存路径目录(C:\Users\c\AppData\Local\Temp\cef\User Data)的子目录
[0704/165213.319:ERROR:cef\libcef\browser\context.cc:181] 缓存路径无效,将默认使用内存存储

C:\Users\c\AppData\Local\Temp\cef\User Data 看来是任务执行的必要工作目录

很有可能内部反而不是直接的一部,外部才没有绕路,ExecuteJavascript Action 第一次初始化没有完成。你的结论是对的 那么原因是什么,我可不想自动固定时间执行时再次重现如故。
否则只能直接走外部js flie

其实我有封装"简单采集"控件,的想法,我知道在当前工具下有几个实现路径,1.直接用脚本能力 执行node或python 插件,直接把 "简单采集"控件,作为一个任务用任务调用这个任务,这是在
工具中内置支持的,不过这样不干脆出错率大,虽然有全局变量和数据库操作插件却仍显复杂

再次分析 如何封装 取列表类

C:\Users\c\AppData\Local\Temp\cef\User Data

这个目录是在什么时候建立的?
这句话让我思考到 可能浏览器没有第一次初始化某些模块,虽然目录是安装软件时建立的 但有些文件和目录却是20分钟前建立的

所以如果下次踩坑了 可以写个判断如果返回不了数据就直接给他 js file 再取值

封装方案最优:xecute JS↓JSON↓Robotask

这里封装为控件有几个变量那就是选择目标的几个字段需要用户级输入或配置例如通过file\xml、ini、sql、窗口会话

TEXT

{
    "list": ".flow-item",
    "fields": {
        "title": ".item-title",
        "url": ".item-title@href",
        "time": ".time",
        "content": ".item-desc span"
    }
}

但在执行时 xecute JS面临在 js代码中传递参数的问题 目前我还没有实践过也不知道实现过程不知道能否取出来值以便得到正确的选择器路径 也就是这份模板的封装和传参

TEXT

const result=[];
document.querySelectorAll(".flow-item").forEach(item=>{

    result.push({

        title:item.querySelector(".item-title")?.innerText,

        url:item.querySelector(".item-title")?.href,

        time:item.querySelector(".time")?.innerText,

        content:item.querySelector(".item-desc span")?.innerText

    });

});

return JSON.stringify(result);

封装简单采集的落地逻辑

直接把 Robotask 的变量替换到 JS 模板中。

例如 Robotask 有变量:

TEXT

const result = [];

document.querySelectorAll("%LIST%").forEach(item => {

    result.push({

        title: item.querySelector("%TITLE%")?.innerText,

        url: item.querySelector("%URL%")?.href,

        time: item.querySelector("%TIME%")?.innerText

    });

});

return JSON.stringify(result);

只要 Execute JavaScript 支持 RoboTask 变量替换即可

如果 Robotask 不支持变量替换怎么办?这就是第二种方案

TEXT


const config = JSON.parse('%CONFIG%');
const result = [];
document.querySelectorAll(config.list).forEach(item => {

    const row = {};

    for(const key in config.fields){

        const selector = config.fields[key];

        if(selector.endsWith("@href")){

            row[key] = item.querySelector(selector.replace("@href",""))?.href;

        }else{

            row[key] = item.querySelector(selector)?.innerText;

        }

    }

    result.push(row);

});

return JSON.stringify(result);

只需要支持传

TEXT

{
  "list": ".flow-item",
  "fields": {
      "title": ".item-title",
      "url": ".item-title@href",
      "time": ".time"
  }
}

遇到不同网站取得值的方法也是不同的

TEXT


、{
  "list": ".flow-item",

  "fields":[

    {

      "name":"title",

      "selector":".item-title",

      "type":"text"

    },

    {

      "name":"url",

      "selector":".item-title",

      "type":"href"

    },

    {

      "name":"time",

      "selector":".time",

      "type":"text"

    },

    {

      "name":"content",

      "selector":".item-desc span",

      "type":"text"

    }

  ]
}

可以增加字段和指定类型
再增加容错逻辑 以后再迭代

TEXT

const el = item.querySelector(field.selector);

if(!el){

    row[field.name] = "";

    continue;

}

某一条新闻没有时间或别的必要字段。整个采集全部停止

Edited on  Jul 04, 2026  By  sytbbt .

Avatar
Posts 142

新的错误,打开浏览器都失败

指定外部执行js C:\Users\c\Downloads\null.js 失败
只有两个步骤 第一个是打开浏览器 第二个就是执行js文件

E: 2026/7/4 19:13:45: Network error: REST 请求失败: Error sending url: https://www.36kr.com/newsflashes/)。

解决过程

直接把任务名全英文 (无效)
重启软件(可打开,但执行外部 js失败 出现internal server error)
打开后给他暂停5秒(无效)
直接复制原36kr (正常)
直接复制一个刚才的任务(无效,只要内容它不认识或执行不了基本上都弹internal server error)
重新新建一个任务(第一步打开空白页面 第二部执行js文件C:\Users\c\Downloads\null.js)
指定另一个js文件 (C:\Users\c\Downloads\null.js,结果E: 2026/7/4 19:25:45: Browser operation failed)
给第一步真正的网址(成功了,单独测试第二步也成功,看来是js注入时编码问题或者是js文件有问题)
notepad++新建一个txt文件 但内容为空 再单独测试第二步(错误validation failed,这是验证失败,看来它要真正进行注入匹配网页取操作)
把内容改为 alert("%CONFIG%");(返回%CONFIG%弹窗和一个错误弹窗value 'result' not found,未这是找到 'result' 值)
把内容加一行return "%CONFIG%"; (返回%CONFIG%和result:"%CONFIG%"共两次弹窗,看来不支持全局参数传参或语法问题)
全局变量config改成小写(无效)
准备查看手册逻辑全局变量在js中的命名规则,https://robotask.com/downloads/robotask.pdf(知道其他地方用变量但在WebAutomation Action "Execute Javascript"的faq根本没找到获取这个功能没有封装外部变量通信只是为了取页面数据而用)

Edited on  Jul 04, 2026  By  sytbbt .

Log in to reply
Navigation
2 Posts
post #1
04 Jul 2026
By Utilisateur