自动化脚本一般是python写的,不过被python的模块引入搞得头疼,不如node每个项目都有自己的依赖包,互不影响,下面展示使用node.js中的puppeteer模块实现自动化脚本
先贴上自己的模块版本:
{
"name": "1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"ddddocr": "^1.0.0",
"opn": "^6.0.0",
"path": "^0.12.7",
"puppeteer": "^21.1.1",
"xlsx": "^0.18.5"
}
}
模块包推荐通过yarn安装,避免安装速度慢、安装失败等问题,yarn安装教程可以参靠我的博客 juejin.cn/post/724109…
1.一般自动化脚本读取xlsx文件,这一块我们单独封装,减少重复代码量
const XLSX = require("xlsx");
// 读取 XLSX 文件
const workbook = XLSX.readFile("./空运(仅报关)模板.xls");
// 获取第一个工作表的名称
const sheetName = workbook.SheetNames[0];
// 通过工作表名称获取工作表对象
const worksheet = workbook.Sheets[sheetName];
// 解析工作表数据
const data = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
// 导出数据
module.exports = data;
2.这边只展示部分功能怎么用,举具体的例子不合适,望理解
// 添加账期自动化脚本
const puppeteer = require("puppeteer");
// 带带弟弟识别验证码模块
const Ddddocr = require("ddddocr"); // 此包有报错,需要 修改 ddddocr/dist/index.js 最后一行为 module.exports = DdddOcr;
// 引入封装好的xlsx文件
const data = require("./xlsx");
//由于所有操作都是异步的,这里用async和awaiw修饰为同步
(async () => {
// 启动浏览器,并设置 headless 为 false
const browser = await puppeteer.launch({
executablePath:
//根据自己谷歌浏览器路径自行更改
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
headless: false,
// 浏览器最大化
defaultViewport: null, // 设置 defaultViewport 为 null
args: [
"--start-maximized",
"--disable-gpu",
"--no-sandbox",
"--disable-dev-shm-usage",
], // 部分参数保证兼容性
});
//打开一个新页面
const page = await browser.newPage();
// 打开指定URL
await page.goto(
"换成你需要的网站"
);
//这种是通过id获取元素的,一般元素加id的比较少,没有id的也可以通过xpath获取
// 输入账号
await page.type("#input1", "admin");
// 输入密码
await page.type("#input2", "admin");
// 获取需要截图的元素的位置和尺寸
const element = await page.$(".pointer");
const boundingBox = await element.boundingBox();
// 执行截图操作
await page.screenshot({ path: "screenshot.png", clip: boundingBox });
// 验证码识别
Ddddocr.create().then(async (ddddocr) => {
const verifyCode = await ddddocr.classification("screenshot.png");
//输入验证码
await page.type("#input3", verifyCode);
});
//通过完整xpath获取元素
//获取登录元素
const [loginButton] = await page.$x(
"/html/body/div/div/div[2]/div[3]/button"
);
//点击登录
await loginButton.click();
await page.waitForSelector("#driver-popover-item");
const { width, height } = await page.evaluate(() => ({
width: window.innerWidth,
height: window.innerHeight,
}));
await page.mouse.click(width / 2, height / 2);
const applyButtonXpath =
"/html/body/div[1]/div/div[1]/div[1]/div[1]/div[1]/span"; // 替换为的完整XPath
const applyButton = await page.waitForXPath(applyButtonXpath);
const applyButtonBoundingBox = await applyButton.boundingBox();
await page.mouse.move(
applyButtonBoundingBox.x + applyButtonBoundingBox.width / 2,
applyButtonBoundingBox.y + applyButtonBoundingBox.height / 2
);
await page.waitForTimeout(3000);
const [financialButton] = await page.$x("/html/body/div[3]/div[1]/div[7]/p");
await financialButton.click();
await page.waitForTimeout(1000);
const [periodManagement] = await page.$x(
"/html/body/div[1]/div/div[3]/div[1]/div/div[1]/div/ul/div[7]/li/div"
);
await periodManagement.click();
await page.waitForTimeout(1000);
const [customerAccounting] = await page.$x(
" /html/body/div[1]/div/div[3]/div[1]/div/div[1]/div/ul/div[7]/li/ul/div[1]/a/li"
);
await customerAccounting.click();
await page.waitForTimeout(1000);
for (let i = 0; i < data.length; i++) {
const [addButton] = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div/div[1]/div/button"
);
await addButton.click();
await page.waitForTimeout(2000);
const elementsCustomerNameInput = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[1]/div[1]/div/div/div/div[1]/input"
);
const customerInput = elementsCustomerNameInput[0];
await customerInput.type(data[i][0]);
await page.waitForTimeout(1000);
const [customerContent] = await page.$x(
"/html/body/div[4]/div[1]/div[1]/ul/li[1]"
);
await customerContent.click();
await page.waitForTimeout(1000);
const deadlineOfAccounting = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[1]/div[2]/div/div/div/div/input"
);
await deadlineOfAccounting[0].click();
await page.waitForTimeout(1000);
const [naturalMonth] = await page.$x(
" /html/body/div[5]/div[1]/div[1]/ul/li[1]"
);
await naturalMonth.click();
await page.waitForTimeout(1000);
const settlementDate = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[1]/div[3]/div/div/div/input"
);
await settlementDate[0].type(" ");
await page.waitForTimeout(1000);
const InvoicingDate = await page.$x(
" /html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[2]/div[1]/div/div/div/input"
);
await InvoicingDate[0].type(" ");
await page.waitForTimeout(1000);
const accountsReceivable = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[2]/div[2]/div/div/div/div[1]/input"
);
await accountsReceivable[0].click();
await page.waitForTimeout(1000);
const [eight] = await page.$x("/html/body/div[6]/div[1]/div[1]/ul/li[2]");
await eight.click();
await page.waitForTimeout(1000);
const elementsInvoiceAddressInput = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[3]/div[1]/div/div/div[1]/input"
);
const invoiceAddressInput = elementsInvoiceAddressInput[0];
await invoiceAddressInput.type(" ");
await page.waitForTimeout(1000);
const elementsInvoicePhoneInput = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[3]/div[2]/div/div/div[1]/input"
);
const invoicePhoneInput = elementsInvoicePhoneInput[0];
await invoicePhoneInput.type(" ");
await page.waitForTimeout(1000);
const elementsInvoiceTypeInput = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[3]/div[3]/div/div/div/div[1]/input"
);
const invoiceTypeInput = elementsInvoiceTypeInput[0];
await invoiceTypeInput.click();
await page.waitForTimeout(1000);
const [specialInvoice] = await page.$x(
" /html/body/div[7]/div[1]/div[1]/ul/li[2]"
);
await specialInvoice.click();
await page.waitForTimeout(1000);
const [addMoneyButton] = await page.$x(
" /html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/form/div/div/div[2]/div[4]/button"
);
await addMoneyButton.click();
await page.waitForTimeout(1000);
const Currency = await page.$x(
"/html/body/div[8]/div/div[2]/div/form/div[1]/div[1]/div/div/div/div[1]/input"
);
await Currency[0].click();
await page.waitForTimeout(1000);
const [money] = await page.$x("/html/body/div[10]/div[1]/div[1]/ul/li[1]");
await money.click();
await page.waitForTimeout(1000);
const bankName = await page.$x(
"/html/body/div[8]/div/div[2]/div/form/div[1]/div[2]/div/div/div/div/input"
);
await bankName[0].click();
await page.waitForTimeout(1000);
const [chinaBank] = await page.$x(
"/html/body/div[11]/div[1]/div[1]/ul/li[1]"
);
await chinaBank.click();
await page.waitForTimeout(1000);
const basicAccount = await page.$x(
"/html/body/div[8]/div/div[2]/div/form/div[2]/div[2]/div/div/div/div/input"
);
await basicAccount[0].click();
await page.waitForTimeout(1000);
const [Yes] = await page.$x("/html/body/div[12]/div[1]/div[1]/ul/li[1]");
await Yes.click();
await page.waitForTimeout(1000);
const province = await page.$x(
"/html/body/div[8]/div/div[2]/div/form/div[3]/div/div/form/div/div[1]/div/div/div/div[1]/input"
);
await province[0].click();
await page.waitForTimeout(1000);
const [BeiJing] = await page.$x(
"/html/body/div[13]/div[1]/div[1]/ul/li[1]"
);
await BeiJing.click();
await page.waitForTimeout(1000);
const city = await page.$x(
"/html/body/div[8]/div/div[2]/div/form/div[3]/div/div/form/div/div[2]/div/div/div/div[1]/input"
);
await city[0].click();
await page.waitForTimeout(1000);
const [BeiJingCity] = await page.$x(
"/html/body/div[14]/div[1]/div[1]/ul/li"
);
await BeiJingCity.click();
await page.waitForTimeout(1000);
const elementsBankAccountInput = await page.$x(
"/html/body/div[8]/div/div[2]/div/form/div[2]/div[1]/div/div/div[1]/input"
);
await elementsBankAccountInput[0].type(" ");
await page.waitForTimeout(1000);
const elementsBankNumberInput = await page.$x(
"/html/body/div[8]/div/div[2]/div/form/div[4]/div[1]/div/div/div[1]/input"
);
await elementsBankNumberInput[0].type(" ");
await page.waitForTimeout(1000);
const elementsOpenBankInput = await page.$x(
" /html/body/div[8]/div/div[2]/div/form/div[4]/div[2]/div/div/div[1]/input"
);
await elementsOpenBankInput[0].type(" ");
await page.waitForTimeout(1000);
const [determineButton] = await page.$x(
"/html/body/div[8]/div/div[3]/span/button[2]"
);
await determineButton.click();
await page.waitForTimeout(1000);
// 获取保存按钮
const [saveButton] = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/div/div[2]/button"
);
await saveButton.click();
await page.waitForTimeout(1000);
// 获取返回上一页按钮
const [returnPage] = await page.$x(
"/html/body/div[1]/div/div[3]/div[2]/div[2]/div/div[2]/div/div/div/div/div[1]/div[1]"
);
await returnPage.click();
await page.waitForTimeout(1000);
}
// 脚本运行结束10s后自动退出
await page.waitForTimeout(10000);
// 关闭浏览器
await browser.close();
})();
这是一段完整的自动化脚本,为安全考虑,所使用网站和输入用户信息部分都做了删改,大部分注释也删除了,仅做参考使用