Используя Cheerio, мне нужно выполнить итерацию на нескольких уровнях для доступа к элементам. Как я могу использовать вложенную итерацию для доступа к элементам и возврата массива объектов? В настоящее время мой код из-за вложенного цикла возвращает массив массивов объектов.
HTML:
<body style = "overflow: hidden">
<div class = "cookie-box"></div>
<div id = "next">
<div></div>
<div>
<main id = "main">
<article>
<div>
<h2>title</h2>
</div>
<div></div>
<div class = "layout">
<form></form>
<section aria-labelledby = "Train">
<ul>
<li>
<p>title</p>
<span>
<a>
<span>123</span>
</a>
<a>
<span>456</span>
</a>
...
</span>
...
</li>
<li></li>
...
</ul>
</section>
</div>
</article>
</main>
</div>
</div>
</body>
код:
const data = [...$('[aria-labelledby = "Train"] li')].map(e => {
return [...$item.find('span a')].map(elem=> {
return {
p: $(e).find("p").text(),
number: $(elem).find('span').text()
}
})
});
что я хотел бы в качестве вывода:
[
{
p: "title",
num: 123
},
{
p: "title",
num: 456
}
]
что я получаю:
[
[
{
p: "title",
num: 123
},
{
p: "title",
num: 456
}
]
]
🤔 А знаете ли вы, что...
С JavaScript можно создавать интерактивные формы и проверять введенные пользователем данные.
Вы можете использовать flatMap
, чтобы удалить этот уровень вложенности:
const cheerio = require("cheerio"); // ^1.0.0-rc.12
const html = `
<section aria-labelledby = "Train">
<ul>
<li>
<p>title</p>
<span>
<a>
<span>123</span>
</a>
<a>
<span>456</span>
</a>
</span>
</li>
</ul>
</section>`;
const $ = cheerio.load(html);
const data = [...$('[aria-labelledby = "Train"] li')].flatMap(li =>
[...$(li).find("span a")].map(a => ({
p: $(li).find("> p").text().trim(),
number: $(a).text().trim(),
}))
);
console.info(data);
Другой подход, позволяющий удалить вложенный цикл, — перебрать внутренние элементы и использовать .closest()
для возврата к контейнеру элемента списка и поиска заголовка:
const data = [...$('[aria-labelledby = "Train"] li span a')].map(
a => ({
p: $(a).closest("li").find("> p").text().trim(),
number: $(a).text().trim(),
})
);
Это нарушает одно из моих практических правил парсинга веб-страниц: «работайте сверху вниз, а не снизу вверх», но в данном случае оба кажутся вполне приемлемыми. Подход «снизу вверх» может оказаться запутанным, как только вам понадобится больше элементов из контейнера или в тех случаях, когда родительский элемент может неожиданно измениться. Если вы обнаружите, что несколько раз тянетесь вверх к разным элементам, подумайте о том, чтобы вернуться к подходу сверху вниз.
См. Очистка таблицы с заголовком слияния и теги cherijs select, которые не находятся внутри другого указанного тега, где приведены более сложные примеры выравнивания вложенного массива в Cheerio.