1

Node 新手,所以这可能是一个对 Node 理解不够好的问题,但基本上我正在尝试使用 Puppeteer 在页面上抓取标题列表。当我在 Chrome 控制台中运行查询时,我会得到一个标题列表。哇!

Array.from(document.querySelectorAll('div.description h3.title')).map(partner => partner.innerText)

(12) ["Jellyfish", "MightyHive", "Adswerve", "55 | fifty-five", "E-Nor", "LiveArea", "Merkle Inc.", "Publicis Sapient", "Acceleration Precision", "Resolute Digital", "PMG", "Kepler Group"]

但是当我在 VS Code 中使用 Node.js 对其进行测试时,我得到一个空数组

const browser = await puppeteer.launch();
  const page = await browser.newPage();
  const url =
    "https://marketingplatform.google.com/about/partners/find-a-partner?utm_source=marketingplatform.google.com&utm_medium=et&utm_campaign=marketingplatform.google.com%2Fabout%2F";
  await page.goto(url);

  const titles = await page.evaluate(() => 
    Array.from(document.querySelectorAll("h3.title"))
      .map(partner => partner.innerText.trim())
  )

$ Node google-test.js
[]

即使使用检查“复制选择器”快捷方式进行精确选择,我也尝试进一步指定选择器,但仍然得到一个空数组。

如果我更模糊,例如选择“h2”,我会得到一个结果,但是一旦我进一步指定它对我来说就结束了。是什么赋予了?

4

2 回答 2

4

因为网站在使用 XHR 加载页面后加载内容,所以只需添加以下内容:-

await page.waitFor('h3.title'); 

这会强制页面等到 h3.title 出现,然后您可以按原样运行代码

const titles = await page.evaluate(() =>  ...

然后一切都应该运行正常,我使用的完整脚本: -

'use strict';

const puppeteer = require('puppeteer');

(async() => {
    const browser = await puppeteer.launch({
        headless: false, 
        defaultViewport : { width: 1600, height: 1600}
      });
    const page = await browser.newPage();

  const url =
    "https://marketingplatform.google.com/about/partners/find-a-partner";
  await page.goto(url);

  await page.waitFor('h3.title');  //this is the magic!

  const titles = await page.evaluate(() =>
    Array.from(document.querySelectorAll("h3.title"))
      .map(partner => partner.innerText.trim())
  )
  console.log(titles)
  await browser.close();

})();  

注意:我关闭了无头模式并设置了更宽的视口,这样我就可以看到发生了什么。在生产中,您不需要这些设置。

于 2019-11-19T19:06:50.497 回答
0

看起来页面上的合作伙伴列表是通过JS动态加载的;在 Chrome 上,左键单击并选择“查看源代码...”以查看开始时实际加载的内容。

合作伙伴列表似乎在滚动上延迟加载......您可能需要以某种方式模拟滚动并等待页面的延迟部分加载以获取您想要的数据。

于 2019-11-19T18:49:52.987 回答