Сглаживание вложенного массива заголовков и нескольких дочерних элементов в Cheerio

Используя 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
  }
 ]
]

Используйте FlatMap вместо карты в первой строке.

Coding Enthusiast 13.07.2024 15:43
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать 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.

Другие вопросы по теме