【发布时间】:2021-05-29 13:27:10
【问题描述】:
我想使用 puppeteer 将一些 HTML 注入到页面上的特定元素中。
必须在执行任何 JavaScript 之前注入 HTML。
我认为有两种方法可以做到这一点:
- 使用
page.evaluateOnNewDocument注入 HTML
这个函数是"is invoked after the document was created",但我不能从中访问 DOM 元素。例如:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('console', consoleObj => console.log(consoleObj.text()));
await page.evaluateOnNewDocument(
() => {
const content = document.querySelector('html');
console.log(content);
}
);
await page.goto(process.argv[2]);
await browser.close();
})();
当我访问一个页面时,这个脚本只会输出换行符。
- 在我注入 HTML 之前,使用
page.setJavaScriptEnabled防止 javascript 执行。就像per the docs 一样,在我重新打开它后它不会开始执行javascript。例如:
我的脚本看起来像这样:
const fs = require('fs');
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const html = fs.readFileSync('./example.html', 'utf8');
await page.setJavaScriptEnabled(false)
await page.goto(process.argv[2]);
await page.evaluate(
content => {
const pageEl = document.querySelector('div.page');
let node = document.createElement('div');
node.innerHTML = content;
pageEl.appendChild(node);
}, html
);
await page.setJavaScriptEnabled(true)
await browser.close();
})();
或者,也可以执行this 之类的操作,尽管对于相当简单的请求而言,这似乎过于复杂。
有没有我忽略的更简单的方法?
干杯
【问题讨论】:
-
至于方式1:脚本执行的时候好像没有DOM。至于2方式:似乎
setJavaScriptEnabled()对page.evaluate()没有影响。有点不清楚您有什么限制:您是否需要在创建 DOM 之后但在执行任何页面脚本之前插入一个元素? -
是的,HTML 必须注入到特定的元素中,所以在加载 DOM 之后,但在执行任何 JavaScript 之前。在页面再次导航之前,使用
setJavaScriptEnabled(true)重新启用 JavaScript 不会产生影响 -
也许您可以尝试在
'domcontentloaded'页面事件上调用page.evaluate(),但成功似乎无法预测。 -
或者您可以设置
MutationObserver和evaluateOnNewDocument()以捕捉添加所需节点的时刻。 -
感谢您的建议。为了给您更多的上下文,我尝试在添加 jQuery 事件侦听器之前注入 HTML。我尝试使用
domcontentloaded,但没有成功。 pastebin.com/zVNvDXGF 这个 sn-p 运行得不够早,无法拦截正在添加的 jQuery 事件侦听器。 (意味着元素不会被足够早地添加)
标签: javascript node.js puppeteer