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

Playwright调用page.evaluate/page.$eval始终返回undefined问题

Playwright evaluate返回undefined问题排查

问题现象

使用Playwright进行网站数据爬取时,调用page.evaluate/page.$eval相关方法,回调内部可以在浏览器控制台正常打印爬取到的数据,但Node侧(终端/命令行)始终拿到undefined返回值。
问题复现代码如下:

const table= await page.$eval("#txnHistoryList > tbody", (table) => {
    let arrayData = [];
    if (table != null) {
      const rows = Array.from(table.querySelectorAll("tr"));
      rows.forEach((row, rowIndex) => {
        if (rowIndex > 1) {
          const td = row.querySelectorAll("td");
          let arrays = {};
          if (td.length > 2) {
            td.forEach((item, tdIndex) => {
              if (tdIndex == 1) {
                const date = item.innerText;
                arrays.date = date ? date.toString().trim() : "";
              }
              if (tdIndex == 2) {
                const transaction = item.innerText;
                arrays.transaction = transaction
                  ? transaction.toString().trim()
                  : "";
              }
              if (tdIndex == 4) {
                const type = item.innerText;
                arrays.type = type ? type.toString().trim() : "";
              }
              if (tdIndex == 5) {
                const paymentAmount = item.innerText;
                arrays.payment_amount = paymentAmount
                  ? paymentAmount.toString().trim()
                  : "";
              }
              if (tdIndex == 6) {
                const balance = item.innerText;
                arrays.balance = balance ? balance.toString().trim() : "";
              }
            });
            arrayData.push(arrays);
          }
        }
      });
    }
    console.log(arrayData);
    return arrayData;
  });

  console.log(tableMutasi);

  const data = {
    data: tableMutasi,
  };
  res.send(data);

根因与修复方案

1. 核心错误:变量名引用不匹配

代码中page.$eval的返回值被赋值给了table变量,但后续打印、组装接口响应时,使用的是从未定义的tableMutasi变量,非严格模式下未赋值的变量默认值就是undefined,自然拿不到爬取结果。
直接统一变量名即可,比如将接收返回值的变量名改为tableMutasi:

// 把接收返回值的变量从table改为tableMutasi,和后续引用保持一致
const tableMutasi = await page.$eval("#txnHistoryList > tbody", (table) => {
    // 回调内部逻辑无需修改
    let arrayData = [];
    if (table != null) {
      const rows = Array.from(table.querySelectorAll("tr"));
      rows.forEach((row, rowIndex) => {
        if (rowIndex > 1) {
          const td = row.querySelectorAll("td");
          let arrays = {};
          if (td.length > 2) {
            td.forEach((item, tdIndex) => {
              if (tdIndex == 1) {
                const date = item.innerText;
                arrays.date = date ? date.toString().trim() : "";
              }
              if (tdIndex == 2) {
                const transaction = item.innerText;
                arrays.transaction = transaction
                  ? transaction.toString().trim()
                  : "";
              }
              if (tdIndex == 4) {
                const type = item.innerText;
                arrays.type = type ? type.toString().trim() : "";
              }
              if (tdIndex == 5) {
                const paymentAmount = item.innerText;
                arrays.payment_amount = paymentAmount
                  ? paymentAmount.toString().trim()
                  : "";
              }
              if (tdIndex == 6) {
                const balance = item.innerText;
                arrays.balance = balance ? balance.toString().trim() : "";
              }
            });
            arrayData.push(arrays);
          }
        }
      });
    }
    return arrayData;
});

console.log(tableMutasi); // 此时可以正常打印爬取到的数组
const data = {
  data: tableMutasi,
};
res.send(data);

2. 可选优化:增加DOM渲染等待

如果修正变量名后偶现拿不到数据,是因为目标DOM还没完成动态渲染就执行了爬取逻辑,可以在$eval调用前增加选择器等待:

// 等待目标表格渲染完成再执行爬取,超时时间可根据页面实际加载速度调整
await page.waitForSelector("#txnHistoryList > tbody", {timeout: 10000});
const tableMutasi = await page.$eval(/* 后续逻辑不变 */);

补充说明:Playwright的evaluate类方法回调运行在浏览器上下文,返回值会经过JSON序列化后传回Node侧,只要返回的是可序列化的普通值(字符串、数字、普通对象/数组、null等,不含DOM节点、函数、Symbol、循环引用)就可以正常传输,当前代码返回的纯文本对象数组完全符合序列化要求,不需要额外做转换处理。


内容的提问来源于stack exchange,提问作者Sultan Achmad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:42:28