Puppeteer:为什么对象在 page.evaluate 函数中返回未定义?

Puppeteer: Why is object returning undefined in page.evaluate function?

我一直在尝试使用 puppeteer 来抓取 Twitch。

这个程序的想法是获取(例如)第一页类别 'Just Chatting' 中每个流的图标、用户名和缩略图。 我认为我的主要代码正在运行,但我尝试 return(属性)的对象被 return 编辑为未定义。

我尝试在函数 log() 中的 console.log 后面添加 await,我也在此处搜索它并读到从评估函数中编辑的值 return 必须是 json 可序列化,我相信它确实包括对象将具有的字符串。任何帮助将不胜感激,谢谢!

let properties = { icon: [], user: [], img: [], link: [] };
const puppeteer = require('puppeteer');
let elements = {
  'https://www.twitch.tv/directory/game/Just%20Chatting': [
    'img[class="InjectLayout-sc-588ddc-0.iyfkau.tw-image.tw-image-avatar"]',
    'a[class="ScCoreLink-udwpw5-0.cxXSPs.tw-link"]',
    'img[class="tw-image"]',
  ],
};
async function scrapeStreams() {
  console.log('scrape started');
  try {
    console.log('try started');
    const browser = await puppeteer.launch({ headless: false });
    const page = await browser.newPage();
    await page.setDefaultNavigationTimeout(0);
    await page.goto(Object.keys(elements)[0], { waitUntil: 'networkidle2' });
    await page.evaluate(
      (properties, elements) => {
        for ([key, value] of Object.entries(elements)) {
          if ((key = Object.keys(elements)[0])) {
            value.forEach((element) => {
              if ((element = Object.values(elements)[0])) {
                el = document.querySelector(element);
                for (let val in el) {
                  datatype = val.src;
                  Object.values(properties)[0].push(datatype);
                }
              } else if ((element = Object.values(elements)[1])) {
                el = document.querySelector(element);
                for (let val in el) {
                  datatype = val.innerHTML;
                  Object.values(properties)[1].push(datatype);
                }
              } else if ((element = Object.values(elements)[2])) {
                el = document.querySelector(element);
                for (let val in el) {
                  datatype = val.src;
                  Object.values(properties)[2].push(datatype);
                }
              }
            });
          }
        }

        return properties;
      },
      properties,
      elements
    );
  } catch (error) {
    console.log('THIS IS THE ERROR: ' + error);
  }
}

async function log() {
  let properties = await scrapeStreams();
  console.log(properties);
}

log();
  1. page.evaluate() 函数参数内部和外部的变量不同:它们在 Node.js 和浏览器上下文之间传输时被复制。因此,当您更改 page.evaluate() 内部的 properties 时,外部的 properties 保持不变。当您在 page.evaluate() 中使用 return properties; 时,您不会保存 returned 值。

  2. 您忘记 return 中的值 scrapeStreams()

但是,您的代码中似乎还有一些其他问题(许多 null 已 returned),但您可以使用另一个问题来解决它们。

// ...
    // FIXED:
    properties = await page.evaluate(
// ...
    // FIXED:
    return properties;
  } catch (error) {
    console.log('THIS IS THE ERROR: ' + error);
  }
}
// ...