playwright-端到端神器(node.js)

3,906 阅读2分钟

基于公司需求,使用node.js抓取目标网页的信息并处理。利用https直接请求可以得到目标网页的html文件。但有些信息是动态插入的,直接请求的html文件不包含这部分信息(例如js动态插入标签)。

playwright很好的解决了我的需求,能获取到页面完全生成的dom文档。

这里粗略说一下我的使用 具体还请移步官方文档

为什么选择playwright

(以下机翻官网)

Playwright Test 是专门为满足端到端测试的需求而创建的。它可以满足您对常规测试运行器的期望,等等。编剧测试允许:

  • 在所有浏览器上运行测试。
  • 并行执行测试。
  • 开箱即用地享受上下文隔离。
  • 在失败时捕获视频、屏幕截图和其他工件。
  • 将您的 POM 集成为可扩展的装置。

安装

npm i -D playwright

使用

const { chromium } = require('playwright');//引用所需包,这里用了chromium内核浏览器
//你可以选择(chromium, firefox and webkit)内核的浏览器

建立页面

const { chromium } = require("playwright"); //引用所需包,这里用了chromium内核浏览器
//你可以选择(chromium, firefox and webkit)内核的浏览器
const run = async function () {
  const waitUntil = "networkidle";

  const browser = await chromium.launch(); //启动游览器
  const context = await browser.newContext(); //创建游览器上下文

  const pageGoto = async function () {
    const page = await context.newPage();//创建页面
    try {
      await page.goto("https:" + "//www.salesmartly.com/"); //模拟访问网站url
    } catch (error) {
      console.log("---页面无法打开,请检查---");
      console.log(error);
      return;
    }
    await page.close();//页面关闭
  };
  pageGoto().then(async () =>awit browser.close());//等待执行完毕,关闭游览器(这里不够严谨,请仅作参考)
};
run();

获取页面元素

const ulElementHandle = await page.$('ul');//使用类似jq的方式查询
const e = await page.$$eval("script");
const e2 = await page.$eval("script");
//支持使用css或者XPath查询
//以上方式皆会返回ElementHandle,注意使用该对象的方式

但需要注意的是,这里的ElementHandle不是我们js常用的类型

可以使用const pageContent = await page.content();获取加载完的页面上下文

再使用cheerio进行对页面的处理,像jq一样使用

个人认为这样较为方便

const cheerio = require("cheerio");
const pageContent = await page.content();
const $ = cheerio.load(pageContent);
const script = $("script");//获取页面的script标签

执行页面脚本

page.evaluateAPI可以在网页的上下文中运行JavaScript函数,并将结果返回到Node.js环境。

const href = await page.evaluate(() => document.location.href);

如果结果是一个Promise或函数是异步的,则evaluate将自动等待直到解决:

const status = await page.evaluate(async () => {
  const response = await fetch(location.href);
  return response.status;
});

传值使用:

const data = { text: 'some data', value: 1 };
// Pass |data| as a parameter.
const result = await page.evaluate(data => {
  window.myApp.use(data);
}, data);

可以在定位元素上使用,将等待元素出现再执行脚本(可以自动等待对应时机执行js脚本,例如等待页面body加载后执行)

const locator = await page.locator("body");
    const trueUrl = await locator.evaluate(() => {
      return document.domain;
    });