我正在尝试抓取包含一堆短信的页面。消息的排列方式与下面的示例类似。我想使用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.
答案 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
}
}
}
});