Очистка эпизодов IMDb с помощью Cheerio.js - возвращается только первая страница телевизионных эпизодов - PullRequest
0 голосов
/ 21 ноября 2018

Работа над соскобом телевизионных эпизодов из IMDb (в плохом состоянии в примере ниже).Проблема заключается в том, что при реализации цикла for возвращается только первая итерация j.

Я предполагаю, что оператор return выходит из цикла, но я не уверен, как решить проблему.

const fetch = require('node-fetch');
const cheerio = require('cheerio');

const searchUrl = 'https://www.imdb.com/find?s=tt&ttype=tv&ref_=fn_tv&q=';
const movieUrl = 'https://www.imdb.com/title/';

async function getEpisodes(searchTerm) {

  //const imdbID = await getID(searchTerm);
  //const numSeasons = await getSeasons(imdbID);

  const imdbID = 'tt0903747';
  const numSeasons = 5;
  const episodes = [];

  for (let j = 1; j <= numSeasons; j++) {
    return fetch(`${movieUrl}${imdbID}/episodes?season=${j}`)
      .then(response => response.text())
      .then(body => {
        const $ = cheerio.load(body);

        $('div[itemProp="episodes"]').each(function (i, element) {
          const airdate = $(element).find('.airdate').text().trim();
          const episodeTitle = $(element).find('a[itemProp="name"]').text().trim();
          const votes = $(element).find('.ipl-rating-star__total-votes').text().trim().match(/\(([^)]+)\)/)[1];
          const rating = $(element).find('.ipl-rating-star ').find('.ipl-rating-star__rating').text().trim().slice(0, 3);

          episode = {
            season: j,
            episodeTitle,
            airdate,
            votes,
            rating
          };
          episodes.push(episode);
        }); 
        return episodes; //Only season 1 is returned.
      }); 
  }
}

1 Ответ

0 голосов
/ 21 ноября 2018

Давайте перепишем функцию, используя стиль асинхронного ожидания.Таким образом мы проверяем, что мы запускаем fetch numSeasons раз, ожидаем их всех и обрабатываем их один за другим.

async function processResponse(response, season) {
    const body = await response.text();
    const $ = cheerio.load(body);

    let episodes = [];
    $('div[itemProp="episodes"]').each(function (i, element) {
        const airdate = $(element).find('.airdate').text().trim();
        const episodeTitle = $(element).find('a[itemProp="name"]').text().trim();
        const votes = $(element).find('.ipl-rating-star__total-votes').text().trim().match(/\(([^)]+)\)/)[1];
        const rating = $(element).find('.ipl-rating-star ').find('.ipl-rating-star__rating').text().trim().slice(0, 3);

        episode = {
            season,
            episodeTitle,
            airdate,
            votes,
            rating
        };

        episodes.push(episode);
    });

    return episodes;
}

async function getEpisodes(searchTerm) {

    //const imdbID = await getID(searchTerm);
    //const numSeasons = await getSeasons(imdbID);

    const imdbID = 'tt0903747';
    const numSeasons = 5;

    let promises = [];

    for (let j = 1; j <= numSeasons; j++) {
        promises.push(fetch(`${movieUrl}${imdbID}/episodes?season=${j}`));
    }

    const responses = await Promise.all(promises);
    return responses.reduce((accumulator, response, index) => {
        return accumulator.concat(await processResponse(response, index + 1));
    }, []);
}
...