You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+Puppeteer主上下文如何从文件引入自定义函数?

在Puppeteer主上下文添加自定义工具函数的实现方法

好问题!你已经熟悉了如何给浏览器页面上下文注入工具函数,而在Node.js侧的Puppeteer主上下文里添加自定义函数其实更简单,完全可以复用Node.js的模块系统和对象扩展逻辑,下面一步步给你演示:

1. 把自定义函数写成独立模块文件

首先,把你的existsText(以及其他需要的工具函数)放到单独的文件里,比如命名为customPuppeteerHelpers.js,用Node.js的模块导出方式对外暴露:

// customPuppeteerHelpers.js
module.exports = {
  // 实现你的existsText逻辑,注意要接收page实例作为参数
  existsText: async (page, targetText) => {
    try {
      // 这里用waitForFunction检查文本是否存在,可根据需求调整实现
      await page.waitForFunction(
        (text) => document.body.textContent.includes(text),
        { timeout: 1500 }, // 可选:设置超时时间,避免无限等待
        targetText
      );
      return true;
    } catch (error) {
      // 超时或找不到文本时返回false
      return false;
    }
  },

  // 可以在这里添加更多自定义工具函数
  waitForAndClick: async (page, selector) => {
    const element = await page.waitForSelector(selector);
    await element.click();
  }
};

2. 在主脚本中引入并使用

接下来有两种常用的使用方式,根据你的习惯选择:

方式一:直接调用函数(最直观)

在主脚本里引入模块后,直接调用函数并传入page实例:

const puppeteer = require('puppeteer');
const { existsText } = require('./customPuppeteerHelpers.js');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  
  await page.goto('https://example.com');
  
  // 直接调用自定义函数,传入page和目标文本
  const isTextPresent = await existsText(page, 'Example Domain');
  console.log(`目标文本是否存在:${isTextPresent}`);

  await browser.close();
})();

方式二:挂载到Page对象上(模拟内置方法)

如果你想让函数像Puppeteer的内置方法(比如page.goto())一样直接通过page.existsText()调用,可以给page对象动态添加属性:

const puppeteer = require('puppeteer');
const customHelpers = require('./customPuppeteerHelpers.js');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // 将existsText绑定到page对象,自动传入当前page实例
  page.existsText = async (targetText) => {
    return customHelpers.existsText(page, targetText);
  };

  // 同理可以绑定其他函数
  page.waitForAndClick = async (selector) => {
    return customHelpers.waitForAndClick(page, selector);
  };
  
  await page.goto('https://example.com');
  
  // 现在可以直接用page.existsText()调用
  const isTextPresent = await page.existsText('Example Domain');
  console.log(`目标文本是否存在:${isTextPresent}`);

  await browser.close();
})();

3. 进阶:给所有新Page实例自动添加工具函数

如果你的脚本会创建多个page实例,不想每次都手动绑定函数,可以封装一个创建page的工具函数,批量绑定所有自定义方法:

const puppeteer = require('puppeteer');
const customHelpers = require('./customPuppeteerHelpers.js');

// 封装带工具函数的page创建函数
async function createPageWithHelpers(browser) {
  const page = await browser.newPage();
  
  // 批量将所有helper函数绑定到page对象
  Object.keys(customHelpers).forEach(helperName => {
    // 使用bind固定第一个参数为当前page实例
    page[helperName] = customHelpers[helperName].bind(null, page);
  });
  
  return page;
}

(async () => {
  const browser = await puppeteer.launch();
  // 使用封装函数创建page,自动拥有所有自定义方法
  const page1 = await createPageWithHelpers(browser);
  const page2 = await createPageWithHelpers(browser);
  
  await page1.goto('https://example.com');
  const page1HasText = await page1.existsText('Example Domain');
  console.log(`page1中目标文本是否存在:${page1HasText}`);

  await browser.close();
})();

关键区别说明

别忘了,evaluateOnNewDocument是把代码注入到浏览器的页面上下文(也就是前端JS运行的window环境),而我们这里操作的是Node.js侧的Puppeteer主上下文,所以完全遵循Node.js的模块导入和对象扩展规则,不需要注入到浏览器环境。

内容的提问来源于stack exchange,提问作者Gilles Quénot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:44:27