如何将 Typescript/Javascript 函数附加到 Puppeteer 页面上下文

问题描述 投票:0回答:2

我正在使用 Puppeteer 在 Typescript 中编写一个网页抓取应用程序。我将一个带有实用函数的 Javascript 文件“附加”到页面实例,以使抓取更容易(这是通过 Pupeteer 的

page.addScriptTag
函数完成的,请参阅 API here)。页面上的实用功能之一可能如下所示:

// functions.ts

export const getLink = (node: Element) => {
  let link = node.querySelector("a");
  return link ? link.href : null;
};

然后就可以使用里面的功能了

page.evaluate
:

// process.ts

import { getLink } from "../functions";

interface LinkArgs {
  page: puppeteer.Page;
  selector: selector;
}

export const getLinkFromPage = async ({ page, selector }): LinkArgs) =>
  page.evaluate((selector) => {
    const link = getLink(selector); // I'm using the function here.
    return link;
  }, selectors);

问题是,当我这样做时,导入在开发过程中失败。 我相信这是因为

import
export
编译的语法在chrome内部不起作用。这是我的浏览器的错误:

Could not get links.  Error: Evaluation failed: ReferenceError: src_1 is not defined
    at __puppeteer_evaluation_script__:2:20
    at ExecutionContext._evaluateInternal (/Users/harrisoncramer/Desktop/Code/projects/gql3.0_schedulers/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:217
:19)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async ExecutionContext.evaluate (/Users/harrisoncramer/Desktop/Code/projects/gql3.0_schedulers/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:106:16
)
Evaluation failed: ReferenceError: src_1 is not defined
    at __puppeteer_evaluation_script__:2:20

我有一个巧妙的解决方法:我将

functions.ts
文件打入编译器,然后从
export
文件中删除所有
functions.js
关键字。然后,我从
import
文件中删除所有
process.ts
语句,如下所示:

// functions.js

const getLink = (node) => {
  let link = node.querySelector("a");
  return link ? link.href : null;
};

// process.js

    // Turning off this import...
    // import { getLink } from "../functions"; 

interface LinkArgs {
  page: puppeteer.Page;
  selector: selector;
}

export const getLinkFromPage = async ({ page, selector }): LinkArgs) =>
  page.evaluate((selector) => {
    const link = getLink(selector); // I'm using the function here.
    return link;
  }, selectors);

然而,这破坏了开发过程中的类型检查!有什么更好的方法来解决这个问题?如何在不破坏 Typescript 类型检查的情况下将已编译的 Javascript 函数导入到页面上?

javascript typescript web-scraping module puppeteer
2个回答
0
投票

page.evaluate
中的任何内容本质上都在 Chrome 的 DevTools 控制台内运行,或者在您所在的相同上下文中运行(如果您这样做的话)。因此,导入在这种情况下不起作用,至少在您尝试的方式下不起作用。您必须像这样显式地将函数传递到上下文中:

const getLink = (node) => {
  let link = node.querySelector("a");
  return link ? link.href : null;
};

// process.js

    // Turning off this import...
    // import { getLink } from "../functions"; 

interface LinkArgs {
  page: puppeteer.Page;
  selector: selector;
}

export const getLinkFromPage = async ({ page, selector }): LinkArgs) =>
  page.evaluate((selector, getLink) => {
    const link = getLink(selector); // I'm using the function here.
    return link;
  }, selectors, getLink);

0
投票

截至 2024 年,

Puppeteer 现在提供了一个

page.exposeFunction()
方法,该方法需要:

  • name
    :函数名称(在浏览器中显示为
    window.name
  • pptrFunction
    :您想要在浏览器上下文中使用的功能。

在浏览器中,您现在可以使用您的功能:

window.name(...)

单击此处查看文档

© www.soinside.com 2019 - 2024. All rights reserved.