你需要了解Promise、async/await 的一些知识, 此文章使用yarn, 你也可以使用npm。
yarn add -D playwright // 会自动下载相对应的浏览器二进制文件
yarn add -D playwright-cli // 可用于记录操作,自动生成代码。
yarn add -D jest jest-playwright-preset // 编写测试使用, 可以忽略
基本使用:
const { chromium } = require('playwright');
(async function test () {
// 开启并设置浏览器
const browser = await chromium.launch({
headless: false,
devtools: true,
slowMo: 200
});
// 新创建一个标签页
const page = await browser.newPage();
// 页面跳转
await page.goto('https://www.baidu.com');
// 在浏览器的上下文中执行某个函数
await page.evaluate(() => console.log('test-start'));
// 选取input元素, 并输入值
await page.fill('input#kw', 'playwright-npm');
// 等待1.5s
await page.waitForTimeout(1500);
// 可传入可以被序列化的参数, #! Function对象不能传递. 不知道从何时起alert不会再阻塞浏览器
await page.evaluate((date) => console.log('test:', date), new Date());
await page.waitForTimeout(5000);
// 关闭页面以及浏览器
await page.close();
await browser.close();
})();
如果出错, 请将 await browser
替换成await (await browser)
尝试一下。
下面来写一个使用谷歌翻译的IIFE
函数
const { chromium } = require('playwright');
(async function translate (rawData) {
const inSelector = `div > textarea.er8xn`;
const outSelector = `div.J0lOec > span.VIiyi > span > span`;
// 开启并设置浏览器
const browser = await chromium.launch({
headless: false,
slowMo: 200
});
// 新创建一个标签页
const page = await browser.newPage();
// 页面跳转
await page.goto('https://translate.google.cn/', {
waitForTimeout: 60000,
waitUntil: 'domcontentloaded'
});
// 等待元素
const stdIN = await page.waitForSelector(inSelector, {
state: 'attached'
});
// 输入测试数据
await stdIN.fill('test');
// 等待显示翻译结果的元素
let stdOUT = await page.waitForSelector(outSelector, {
timeout: 1500
});
// 声明变量
let preVal;
let outVal = await stdOUT.innerText();
if (outVal !== '测试') {
await page.waitForTimeout(1000);
// 获取最新的值
outVal = await page.$eval(outSelector, e => e.innerText);
if (outVal !== '测试') {
throw new Error('链接失败,请重新尝试。');
}
} else {
console.log('链接成功');
preVal = outVal;
}
let translateData = [];
// 进行翻译,此处不用map or forEach 使用其他数组API 请慎重
for (const item of Object.values(rawData)) {
await stdIN.fill(item);
// 缓和时间。 缓和时间与网速度有关
await page.waitForTimeout(1500);
// 获取最新的值
let outData = await page.$eval(outSelector, e => e.innerText);
console.log(preVal, outData, 'gap--');
await page.waitForTimeout(1000);
if (preVal === outData) {
// 最大缓和时间
await page.waitForTimeout(1000);
outData = await stdOUT.innerText();
}
preVal = outData;
translateData.push({
item,
outData
});
}
// 关闭页面以及浏览器
await page.close();
await browser.close();
console.log('close---', translateData);
return translateData;
})(['python', 'good', 'left', 'right', 'attachment']).catch(() =>
console.log('err')
);
就这样吧,其实还是由很大的优化空间,此文章只是做个简单的介绍,官方文档也一直在更新, 与我刚接触时的API已经变了不少, 高级技巧请到官方文档学习哟!