使用Puppeteer,在执行页内JS之前,如何在页面上下文中运行完整DOM的脚本?
例如,在运行任何页面JS之前,如何运行以下脚本从alt
元素中删除img
属性?
document.querySelectorAll('img[alt]').forEach(
e => e.removeAttribute('alt')
)
(page.evaluateOnNewDocument
看起来很有用,但它似乎是在页面内容可用之前执行的 - 在它运行的时候,页面是空白的。)
答案 0 :(得分:6)
我认为实现目标的方法是执行:
page.setJavaScriptEnabled(false)
page.setJavaScriptEnabled(true)
page.goto(`data:text/html,${HTMLWithoutScript}`)
page.addScriptTag({ content: script })
以下是您可疑示例的可视化:
const puppeteer = require('puppeteer');
const html = `
<html>
<head></head>
<body>
<img src="https://picsum.photos/200/300?image=1062" alt="dog ">
<img src="https://picsum.photos/200/300?image=1072" alt="car ">
<div class="alts">List of alts: </div>
<script>
const images = document.querySelectorAll('img');
const altsContainer = document.querySelector('.alts');
images.forEach(image => {
const alt = image.getAttribute('alt') || 'missing alt ';
altsContainer.insertAdjacentHTML('beforeend', alt);
})
</script>
</body>
</html>`;
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(`data:text/html,${html}`);
await page.evaluate(() => {
document.querySelectorAll('img[alt]').forEach(
e => e.removeAttribute('alt')
)
});
await page.screenshot({ path: 'image.png' });
await browser.close();
})();
此代码生成:
所以删除alts在这里不起作用。
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setJavaScriptEnabled(false);
await page.goto(`data:text/html,${html}`);
const { script, HTMLWithoutScript } = await page.evaluate(() => {
const script = document.querySelector('script').innerHTML;
document.querySelector('script').innerHTML = '';
const HTMLWithoutScript = document.body.innerHTML;
return { script, HTMLWithoutScript }
});
await page.setJavaScriptEnabled(true);
await page.goto(`data:text/html,${HTMLWithoutScript}`);
await page.evaluate(() => {
document.querySelectorAll('img[alt]').forEach(
e => e.removeAttribute('alt')
)
});
await page.addScriptTag({ content: script });
await page.screenshot({ path: 'image.png' });
await browser.close();
})();
这将产生您在问题中所期望的结果:
答案 1 :(得分:0)
您可以将脚本标记移动到body而不是head。然后使用document onload事件,您可以执行脚本。根据MDN,此事件在加载对象时触发。以下是示例代码
function removeAlt(){
document.querySelectorAll('img[alt]').forEach((e)=>{
e.removeAttribute('alt');
});
}
&#13;
<body onload="removeAlt()">
<img src="http://placehold.it/64x64" alt="1">
<img src="http://placehold.it/64x64" alt="2">
</body>
&#13;
让我知道这是否符合您的要求,我测试过并且功能是从图像中移除alt标签