.evaluate
不返回 DOM 元素。而且,您正在尝试修改不同上下文中的元素。浏览器窗口中的页面和您在 nodeJS 中拥有的上下文完全不同。
以下是处理 React 和 Puppeteer 的另一种方法。
首先,我有一个入口文件,在其中将该函数导出到 window 。
通过这样做,我可以轻松地从浏览器上下文中访问它。您可以导出它并尝试使用 expose-loader 等工具。我将使用 webpack 进行构建。
import React from 'react';
import { render } from 'react-dom';
function Hello() {
return <h1>Hello from React</h1>;
}
function renderIt(domNode) {
render(<Hello />, domNode);
}
window.renderIt = renderIt;
在webpack配置中,
const webpack = require('webpack');
const loaders = [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['babel-preset-es2015', 'babel-preset-react'],
plugins: []
}
}
];
module.exports = {
entry: './entry.js',
output: {
path: __dirname,
filename: 'bundle.js',
libraryTarget: 'umd'
},
module: {
loaders: loaders
}
};
现在每当我运行webpack时,它都会为我创建一个bundle.js文件。现在让我们来看一个puppeteer文件,
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://github.com');
await page.addScriptTag({ path: require.resolve('./bundle.js') });
await page.evaluate(() => {
renderIt(document.querySelector('div.jumbotron.jumbotron-codelines > div > div > div > h1'));
});
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
正如您所看到的,我正在使用之前向窗口公开的 renderIt 函数。当我运行它时,这就是结果,
![enter image description here](https://istack.dev59.com/QvZsx.webp)
甜!来自React的问候 :)
哦!如果由于CORS问题而无法执行页面上的脚本,您可以使用旧的injectFile函数进行注入,直到他们修复addScriptTag函数的问题或从injectFile中删除弃用。
const fs = require('fs');
async function injectFile(page, filePath) {
let contents = await new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) return reject(err);
resolve(data);
});
});
contents += `//# sourceURL=` + filePath.replace(/\n/g, '');
return page.mainFrame().evaluate(contents);
}