木偶师迭代 div,然后从结果迭代子元素



我想从HTML返回一个对象,如下所示:

.HTML

<div id="collection">
<div class="div">
<h1 class="title">Title 1</h1>
<ul class="list">
<li>list item 1</li>
<li>list item 2</li>
<li>list item 3</li>
</ul>
</div>
<div class="div">
<h1 class="title">Title 2</h1>
<ul class="list">
<li>list item 1a</li>
<li>list item 2a</li>
<li>list item 3a</li>
<li>list item 4a</li>
</ul>
</div>
<div class="div">
<h1 class="title">Title 3</h1>
</div>
</div>

所需结果:

{
title: "Title 1",
list:{
item: "list item 1",
item: "list item 2",
item: "list item 3"
}
},
{
title: "Title 2",
list:{
item: "list item 1a",
item: "list item 2a",
item: "list item 3a",
item: "list item 4a"
}
},
{
title: "Title 3",
list:{}
}

到目前为止,我有:

const result = await page.$$eval('div.div, (divs) => divs.map((div) => {
return {
title: div.querySelector('.title').innerText,
}
}));
console.log(result) 

我不确定如何使用 page.$$eval 来迭代另一个元素;在这种情况下是 ul。 任何帮助将不胜感激。

谢谢

你可以用Puppeteer这样做。只需取消注释page.evaluate()功能即可。我只是评论了它,以便您可以运行代码片段并查看结果。

您不能有多个具有相同键的对象条目,因此更好的解决方案可能是返回一个包含li值的数组,因为键无论如何都无关紧要,对吧?

const result = []
//await page.evaluate(() => {
const divs = document.querySelectorAll('.div')
divs.forEach(div => {
const obj = {
title: div.querySelector('.title').innerText,
list: [...div.querySelectorAll('ul li')].map(i => i.innerText)
}
result.push(obj)
})
//})
console.log(result)
<div id="collection">
<div class="div">
<h1 class="title">Title 1</h1>
<ul class="list">
<li>list item 1</li>
<li>list item 2</li>
<li>list item 3</li>
</ul>
</div>
<div class="div">
<h1 class="title">Title 2</h1>
<ul class="list">
<li>list item 1a</li>
<li>list item 2a</li>
<li>list item 3a</li>
<li>list item 4a</li>
</ul>
</div>
<div class="div">
<h1 class="title">Title 3</h1>
</div>
</div>

尝试在您的木偶剧本上执行以下操作,我认为它可能会起作用:

const values = await page.evaluate(() => {
const titles = Array.from(document.querySelectorAll('.title')).map(el => el.innerText); // this will get you an array with the titles  
const list = Array.from(document.querySelectorAll('.list')).map(el => Array.from(el.children).map(elm => elm.innerText));
const endArray = titles.map((el, index) => {
return {
title: el,
list: list[index],
}
})
return endArray;
});

您不能像尝试的那样拥有具有重复属性的对象。最好将列表定义为数组,因为您知道列表具有重复类型的数据。

最新更新