使用Puppeteer page.evaluate()时获得不同的结果

时间:2020-01-04 15:23:08

标签: puppeteer

为什么这样做时我的脚本会产生正确的结果?

let data = await page.evaluate(async () => {

  let multipleVideosUnorderedList = await document
    .querySelector('article > div')
    .querySelector('ul');

  let video = [];

  if (multipleVideosUnorderedList != null) {

    let multipleVideosList = multipleVideosUnorderedList.children;
    console.log(multipleVideosList);

    for (i = 0; i < multipleVideosList.length; i++) {
      let rightBtn = document.querySelector(
        'button > div.coreSpriteRightChevron'
      );
      if (rightBtn) {
        await rightBtn.parentNode.click();
      }
      let videoUrl = multipleVideosList[i].querySelector('video');
      if (videoUrl) {
        video.push(videoUrl.getAttribute('src'));
      }
    }
  } else {
    video.push(document.querySelector('video').getAttribute('src'));
  }

  return {
    video
  };
});

console.log(data);

但是当它归结为:

let er = await page.evaluate(() => {

  let multipleVideosUnorderedList = document.querySelector('article > div').querySelector('ul');

  return {
    multipleVideosUnorderedList
  }
});

console.log(er);

结果不确定。我知道前者中有很多代码,但是我只是想看看它能产生正确的元素,然后再继续学习其他内容。

这个想法是将代码块中的document.querySelector取出并清理,以尝试使用page.$(selector)

1 个答案:

答案 0 :(得分:1)

只有serializable个对象可以进出page.evaluate,而querySelectorAll / querySelector找到的NodeList和Node却不可以这样的东西。

您可能希望找到一个可能包含多个视频的无序列表。如果是这种情况,您可以通过以下方式重写代码:

let outerVideos = await page.evaluate(() => {
  // convert the NodeList to an array
  let videos = [...document.querySelectorAll('article > div video')]
     // for each member of the array replace the video node with its src value
    .map(video => video.getAttribute('src')); 

  return videos;
});

console.log(outerVideos);