运行 JavaScript 在干净的 chrome/puppeteer 上下文中
Run JavaScript in clean chrome/puppeteer context
我正在尝试 运行 JavaScript 以内容抓取为目标的页面上下文。使用 puppeteer,我可以轻松地在页面上下文中调用 evaluate()
和 运行 一段 JavaScript。所以我基本上只是在页面上评估一个document.querySelector
:
const puppeteer = require('puppeteer');
const url = 'file:///C:/Users/roel/puppettest/index.html';
puppeteer.launch({headless: false}).then(async browser => {
const page = await browser.newPage();
await page.goto(url, {waitUntil: 'domcontentloaded'});
const value = await page.evaluate(() => document.querySelector('div').textContent);
if (value === 'Hello') {
console.log('Works');
} else {
console.log('Nope :-(');
}
});
这是我提到的页面:
<html>
<body>
<div>Hello</div>
<script>
var div = document.createElement('div');
div.textContent = 'Whooh!';
document.body.appendChild(div);
document.querySelector = null;
</script>
</body>
</html>
所以这就是问题所在:我评估的代码 运行 是 document.querySelector
,但我加载的页面将其设置为 null
。混乱接踵而至。所以... 我想确保我 运行 的 JavaScript 在干净的上下文中 运行 .
第一个想法:
我可以只检索生成的 HTML 并围绕 DOM 创建一个新的 JavaScript 上下文。 运行 a page.content()
检索 HTML 和...哦,它不是当前的 HTML,它是初始的 HTML(例如 document.createElement()
没有执行)。 运行宁 page.evaluate(() => document.body.innerHTML)
假设页面没有在 document
的 body
属性 上添加 Object.defineProperty
就可以工作。但是没有这样的gua运行tee。有没有办法在不触及 JS 上下文的情况下检索当前 HTML?
第二个想法:
Chrome 扩展 运行 在它们自己的 JavaScript 上下文中可以访问 DOM,并且只能访问 DOM。这正是我所追求的。查看 puppeteer
文档,没有迹象表明要在 puppeteer 本身中创建这样的上下文。还是有但我错过了?
...
那么我该如何获得一个干净的 JS 上下文来运行 查询呢?
EDIT 我读错了 .content()
的输出。 HTML 包括在内。所以,第一个想法确实有效。我仍然很好奇第二个想法是否可以实现,因为它更受欢迎。
您可以使用.content()
检索当前时间点的HTML。编辑前的问题错误地认为 .content()
返回了原始问题。 运行 将 HTML 转换为 jsdom
允许您在 DOM 上执行 JS 而不受原始页面的影响。
我正在尝试 运行 JavaScript 以内容抓取为目标的页面上下文。使用 puppeteer,我可以轻松地在页面上下文中调用 evaluate()
和 运行 一段 JavaScript。所以我基本上只是在页面上评估一个document.querySelector
:
const puppeteer = require('puppeteer');
const url = 'file:///C:/Users/roel/puppettest/index.html';
puppeteer.launch({headless: false}).then(async browser => {
const page = await browser.newPage();
await page.goto(url, {waitUntil: 'domcontentloaded'});
const value = await page.evaluate(() => document.querySelector('div').textContent);
if (value === 'Hello') {
console.log('Works');
} else {
console.log('Nope :-(');
}
});
这是我提到的页面:
<html>
<body>
<div>Hello</div>
<script>
var div = document.createElement('div');
div.textContent = 'Whooh!';
document.body.appendChild(div);
document.querySelector = null;
</script>
</body>
</html>
所以这就是问题所在:我评估的代码 运行 是 document.querySelector
,但我加载的页面将其设置为 null
。混乱接踵而至。所以... 我想确保我 运行 的 JavaScript 在干净的上下文中 运行 .
第一个想法:
我可以只检索生成的 HTML 并围绕 DOM 创建一个新的 JavaScript 上下文。 运行 a page.content()
检索 HTML 和...哦,它不是当前的 HTML,它是初始的 HTML(例如 document.createElement()
没有执行)。 运行宁 page.evaluate(() => document.body.innerHTML)
假设页面没有在 document
的 body
属性 上添加 Object.defineProperty
就可以工作。但是没有这样的gua运行tee。有没有办法在不触及 JS 上下文的情况下检索当前 HTML?
第二个想法:
Chrome 扩展 运行 在它们自己的 JavaScript 上下文中可以访问 DOM,并且只能访问 DOM。这正是我所追求的。查看 puppeteer
文档,没有迹象表明要在 puppeteer 本身中创建这样的上下文。还是有但我错过了?
...
那么我该如何获得一个干净的 JS 上下文来运行 查询呢?
EDIT 我读错了 .content()
的输出。 HTML 包括在内。所以,第一个想法确实有效。我仍然很好奇第二个想法是否可以实现,因为它更受欢迎。
您可以使用.content()
检索当前时间点的HTML。编辑前的问题错误地认为 .content()
返回了原始问题。 运行 将 HTML 转换为 jsdom
允许您在 DOM 上执行 JS 而不受原始页面的影响。