使用操纵up

时间:2019-11-21 02:26:11

标签: puppeteer

我正在尝试抓取包含一堆短信的页面。消息的排列方式与下面的示例类似。我想使用puppeeter创建对象数组。每个对象将包含每个消息的内部文本,不包括元素之一。

我要构建的数组应类似于:

const messages = [{name: 'Greg', textMessage: 'Blah Blah Blah'}, {name: 'James', textMessage: 'Blah Blah Blah'},{name: 'Sam', textMessage: 'Blah Blah Blah'}]

示例:HTML标记

<div class="messages">
  <div class="message">
    <a class="name">Greg</a>
    <p class="element-you-dont-want">Don't scrap this</p>
    <p class="textMessage">Blah Blah Blah</p>
  </div>
  <div class="message">
    <a class="name">James</a>
    <p class="element-you-dont-want">Don't scrap this</p>
    <p class="textMessage">Blah Blah Blah</p>
  </div>
  <div class="message">
    <a class="name">Sam</a>
    <p class="element-you-dont-want">Don't scrap this</p>
    <p class="textMessage">Blah Blah Blah</p>
  </div>
</div>

我当前的代码创建两个数组,一个用于命名,另一个用于textMessages,然后必须将它们组合。有没有更有效的方法来做到这一点。

 const names = await page.evaluate(
      () =>  Array.from(document.querySelectorAll("div.messages a.name")).map(name => name.innerText)
    );
    const textMessages = await page.evaluate(
      () =>  Array.from(document.querySelectorAll("div.messages p.textMessage")).map(textMessage => textMessage.innerText)
    );

... From here I combine the two into an object of arrays. 

2 个答案:

答案 0 :(得分:2)

$$eval中有一个Page函数,该函数在上下文中转换为Array.from(document.querySelectorAll(selector)),并将其作为第一个参数传递给pageFunction

用法:

const result = await page.$$eval('div.message', (msgs) => msgs.map((msg) => {
            return {
                name: msg.querySelector('a.name').innerText,
                textMessage: msg.querySelector('a.textMessage').innerText
            }})
    );

答案 1 :(得分:0)

您可以将它们刮在一起,

page.evaluate(() => {
  const messages = [...document.querySelectorAll("div.message")]; // notice this is not .messages
  return messages.map(message => {
      return {
        name: message.querySelector('a.name').innerText,
        textMessage: message.querySelector('a.textMessage').innerText
      }
    }
  }
});