如何在Chrome+Puppeteer的evaluate()上下文添加脚本与自定义函数?
在Puppeteer的page.evaluate()中添加自定义脚本与函数的方法
当然可以!在Puppeteer里,我们完全能在page.evaluate()的上下文里注入自定义脚本和函数,实现类似CasperJS/PhantomJS那样的便捷功能。下面给你详细讲两种常用的实现方式:
一、注入外部辅助脚本到页面上下文
如果你已经有现成的辅助函数文件(比如包含XPath工具函数的helpers.js),最方便的方式是用page.addScriptTag()先把脚本注入到目标页面中。这样脚本里的函数会成为页面全局对象的一部分,后续在page.evaluate()里就能直接调用。
举个实际的例子:
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // 注入本地的辅助脚本文件 await page.addScriptTag({ path: './helpers.js' }); // 现在在evaluate上下文里就能直接调用脚本里的x函数了 const allLinks = await page.evaluate(() => { return x('//a/@href'); // 调用自定义的XPath查询函数 }); console.log('提取到的链接:', allLinks); await browser.close(); })();
假设你的helpers.js里定义了这样的XPath函数:
// helpers.js window.x = function(xpathExpression) { const result = document.evaluate( xpathExpression, document, null, XPathResult.ANY_TYPE, null ); const results = []; let currentNode; while (currentNode = result.iterateNext()) { // 根据节点类型返回对应的值,比如属性值、文本内容等 results.push(currentNode.value || currentNode.textContent || currentNode.href); } return results; };
二、直接在evaluate中定义或传递自定义函数
如果不想依赖外部文件,你也可以直接在page.evaluate()的上下文里定义函数,或者把外部定义的函数作为参数传递进去(注意:传递的函数必须是可序列化的,不能包含Node.js专属的API)。
方式1:直接在evaluate内部定义函数
await page.evaluate(() => { // 直接在浏览器上下文定义XPath工具函数 const x = function(xpathExpr) { const result = document.evaluate(xpathExpr, document, null, XPathResult.ANY_TYPE, null); const nodes = []; let node; while (node = result.iterateNext()) { nodes.push(node.value || node.textContent || node.href); } return nodes; }; // 立刻调用这个函数提取链接 return x('//a/@href'); });
方式2:从Node.js上下文传递函数到浏览器
// 在Node.js上下文定义XPath函数 const xPathHelper = function(xpathExpr) { const result = document.evaluate(xpathExpr, document, null, XPathResult.ANY_TYPE, null); const nodes = []; let node; while (node = result.iterateNext()) { nodes.push(node.value || node.textContent || node.href); } return nodes; }; // 在evaluate中传递并调用这个函数 const links = await page.evaluate((helperFunc) => { return helperFunc('//a/@href'); }, xPathHelper); // 把函数作为参数传给evaluate
一些关键注意事项
page.evaluate()的上下文是浏览器页面的沙箱环境,和Node.js的上下文完全隔离,所以不能直接访问Node.js里的变量、模块或API,必须通过参数传递或者注入脚本的方式共享。- 如果你的辅助函数依赖第三方库,也可以用
page.addScriptTag()注入CDN链接的库,比如:await page.addScriptTag({ url: 'https://cdn.example.com/some-library.js' })。
内容的提问来源于stack exchange,提问作者MevatlaveKraspek
相关产品推荐
相关产品推荐

