基于公司需求,使用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;
});