浏览器节点

浏览器节点是WEB UI的运行容器,通过NodeJS脚本语言控制和获取浏览器中运行网页的数据、事件、内容等,浏览器节点只能在本地运行,需要安装客户端。录制操作能自动化生成多种语言,如NodeJS(javascript)、Java、C#、Python语言。当前平台能支持NodeJS Libray录制和执行,其他语言只支持录制和自动生成,不支持直接运行。

浏览器节点最典型的应用就是网络爬虫、WEB UI自动化测试、WEB UI自动化执行。

安装

1、安装客户端,下载地址:

MacOS-x64 客户端下载

Windows-x64 客户端下载

客户端在MacOS操作系统安装后打开时,会有无法认证开发者提示:移到废纸篓或取消,选择取消,再到系统偏好设置->安全性与隐私->仍要打开->打开。

注:如需MacOS arm芯片操作系统、Linux操作系统、Windows 32位操作系统客户端需求,请联系客服。

如果需要运行浏览器节点或录制浏览器操作,还需要安装Node和浏览器插件。

2、检查系统环境变量,客户端菜单栏点击查看Node版本,如果Node版本是18+,可运行脚本录制功能。如果版本低于18,需要删除本地Node版本,并安装Node(建议安装Node长期稳定版v20.17.0),同时设置好环境变量。

进入NodeJs下载

3、在客户端菜单栏中点击安装,根据需要选择安装,至少安装一个浏览器,建议安装Chromium。在录制脚本中选择的浏览器必须在此安装好。安装浏览器需要耐心等待几分钟,安装完成后会有提示。

安装的是浏览器内核,对应浏览器为:Chromium->Chrome、Edge、其他基于Chromium内核的浏览器,Webkit->Safari

特点

浏览器节点可以和其他类型的节点混合串联、并联运行

本引擎的节点是并发运行的,提高了运行效率

NodeJS语言简洁易用

集成了playwright框架,利用playwright API进行快速开发

可录制脚本,自动生成

第一个应用

创建一个包含浏览器节点的流程,建立一个登录浏览器节点和查看订单浏览器节点。

一、创建流程

登录客户端,建立一个测试流程,如图:

准备测试系统

本案例网址是www.jd.com,需要提前注册一个测试账户。如果你已可登录的测试系统,可以更换。

二、编辑登录系统节点脚本

浏览器节点编辑脚本编辑两种方式,1、直接在脚本编辑器中编辑脚本 2、脚本录制,自动生成。

脚本录制是实际工作中使用最多的脚本生成工具,双击需要录制脚本的浏览器节点->点击规则引擎页签->点击录制脚本,打开脚本录制参数设置页,参数说明如下:

访问地址

访问地址是运行网站的地址,如果为空,在脚本录制浏览器也可输入。本应用输入:www.jd.com

目标程序

目标程序默认设置为Nodejs/Library,这个是目标生成的脚本语言。本引擎浏览器节点只支持NodeJs语言,但可以生产全部可选择的语言:NodeJS、Java、Python、.NET C#

浏览器

浏览器默认设置为chromium,其他还支持:firefox、webkit内核浏览器。最新的windows浏览器选chromium内核。

认证

认证是网站需要登录的token\cookies认证,登录的节点选择:保存认证信息,登录后其他节点选择:载入认证信息。不需要登录认证的选择不设置。本应用的登录节点选择保存认证信息。

认证文件

认证文件是token\cookies保存的json文件,默认为auth.json,需要修改为本机的绝对路径,如macos: /Users/jifrog/auth/auth.json。防止多个系统需同时登录,文件被覆盖,不同流程或节点需要保存为不同的路径或不同的文件名,文件格式必须是json格式。

设备型号

设备型号一般不需要设置,除非需要手机等移动设备使用

其他参数,根据需要设定

参数输入完成,点击开始录制,会出现两个界面,一个是浏览器,另一个是脚本监测器,你观察一下浏览器类型是否你上面参数内核选择的浏览器一致,浏览器打卡的网站是否是参数网址一致,无误后即可登录操作。

点击账号密码登录,切换为账户、密码登录界面。输入手机号和密码,勾选同意条款,点击登录,完成登录操作。

你会发现脚本监测器里多了一些代码,监测器里初始化代码是根据我们参数自动生成的,后续增加的代码是根据我们的操作自动生成的,需要注意的是录制脚本时随意的点击和无效的操作都会自动生成不必要的代码,操作失误后可以手动删除代码或重新录制。

代码如下:

                
const { chromium } = require('playwright');

(async () => {
    const browser = await chromium.launch({
    headless: false
    });
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('https://www.jd.com/');
    await page.getByRole('link', { name: '你好,请登录' }).click();
    await page.locator('.login-tab > a').first().click();
    await page.goto('https://www.jd.com/');

    // ---------------------
    await context.storageState({ path: '/Users/jifrog/auth/jd.json' });
    await context.close();
    await browser.close();
})();
                
            

监测的代码会自动同步到脚本编辑器,录制完毕后,关闭录制浏览器页面,并手动在代码编辑器中的最后增加一行代码:return true;在运行环境中表示执行完成后继续往后路由执行,这个和其他节点是一致的。

节点编辑器代码如下:

我们可以调式代码,点击执行脚本,发现自动登录后就自动关闭了。调式代码时可以注释关闭浏览器代码:

//await context.close();

//await browser.close();

在编辑器中执行以上代码,需要人工辅助重新登录,这些大型的网站安全性较高,需要各种动态辅助的登录方式,这个步骤主要是登录后保存认证信息。可以用户名和密码登录、APP扫码登录、手机验证码登录、第三方认证登录。

第三、我的订单节点录制脚本

输入参数:访问网址:https://order.jd.com/center/list.action

认证:选择载入认证信息

认证文件:输入登录时的文件路径和文件名:/Users/jifrog/auth/jd.json(路径和文件名必须和登录时一致)

开始录制,代码如下:

                
const { chromium } = require('playwright');

(async () => {
    const browser = await chromium.launch({
    headless: false
    });
    const context = await browser.newContext({
    storageState: 'auth/jd.json'
    });
    const page = await context.newPage();
    await page.goto('https://order.jd.com/center/list.action');

    // ---------------------
    await context.close();
    await browser.close();
    return true;
})();
                
            

可以注释关闭代码,查看运行结果

无痕模式

无痕模式,是一种浏览器功能,旨在提供一种更私密的浏览体验,使你在浏览网页时不会留下任何痕迹。这种模式通过阻止浏览器保存你的浏览历史、搜索记录、下载信息以及Cookie等数据,从而保护你的隐私。第一个应用案例就是浏览器无痕模式。无痕模式下,浏览器右上角会显示"无痕模式"标志字样。

代码如下:

        
const { chromium } = require('playwright');  // Or 'firefox' or 'webkit'.

(async () => {
    const browser = await chromium.launch();//无痕模式启动,返回一个浏览器实例
    const page = await browser.newPage();
    await page.goto('https://jifrog.com');
    // other actions...
    await browser.close();
})();
        
    

非无痕模式

非无痕模式是浏览器正常的浏览模式。有些网站在无痕模式下是不能使用的,那么可以用 launchPersistentContext 非无痕模式启动浏览器。launchPersistentContext会持久化一个浏览器上下文,数据存储于指定目录,并返回上下文。

用法

launchPersistentContext

await browserType.launchPersistentContext(userDataDir, options);

参数

userDataDir string

持久化数据存储目录

options Object (optional)

acceptDownloads boolean (optional)

是否下载所有附件,默认为true,下载所有附件。

args Array (optional)

--remote-debugging-port :端口号',其他详见 参数说明

baseURL string (optional)

当使用page.goto()、page.route()、page.waitForURL()、page.waitForRequest()或page.waiteForResponse()时,它会通过使用URL()构造函数构建相应的URL。默认不设置。

例子:http://localhost:3000/bar.html,baseURL设置为 http://localhost:3000,那后续节点访问只需要page.goto('/bar.html')

headless boolean (optional)

是否无头模式,默认为true

其他参数详见参数说明

返回

Promise:BrowserContext

案例一

创建一个流程,建立两个节点A和B,A节点完成非无痕模式持久化qingflow系统登录数据,B节点完成免登录访问

A节点登录
        
const { chromium } = require('playwright');

(async () => {
    const dir = "/Users/jifrog/qingflow";//指定用户数据绝对路径目录,目录不存在会自动建立目录。此处是macos系统地址,windows设置如:const dir = "c:\path";
    //创建一个context并持久化。指定一个没被占用的端口号。
    const context = await chromium.launchPersistentContext(dir,{headless: false,args :['--remote-debugging-port=9222']});
    //创建page
    const page = await context.newPage();
    //根据page完成系统登录,认证信息cookies和token会被持久化保存,后续节点再次访问不需要认证。
    await page.goto('https://accounts.qingflow.com/acc/passport/login');
    await page.getByText('账号密码登录').click();//第一次运行切换至密码登录,第二次再次运行,如报错,需注释此代码。因为存在缓存已切换,无需代码执行。
    await page.getByRole('textbox', { name: '请输入手机号/邮箱' }).click();
    await page.getByRole('textbox', { name: '请输入手机号/邮箱' }).fill('136********');
    await page.getByPlaceholder('请输入密码').click();
    await page.getByPlaceholder('请输入密码').fill('******');
    await page.getByLabel('').check();
    await page.getByRole('button', { name: '登录' }).click();
    return true;
})();
        
    

以上代码也可以用录制的方式完成,只需要替换录context部分代码

B节点
        
const { chromium } = require('playwright');
(async () => {
    const browser = await chromium.connectOverCDP('http://localhost:9222');//端口号必须和A节点设置一致
    const defaultContext = browser.contexts()[0];//不能创建上下文,只能返回A节点的上下文,A、B节点是共用一个context
    //const page = defaultContext.pages()[0];//返回context的第一个page。
    const page = await defaultContext.newPage();//新建page。
    await page.goto('https://qingflow.com/index/create');
    //await page.close();//关闭page,如果这是浏览器最后一个page,此时会连同浏览器一起关闭。
    return true;
})();