Парсинг рекомендаций фильмов из IMDb

Парсинг рекомендаций фильмов из IMDb

Сегодня утром за чашкой кофе я открыл Хабр и увидел там статью Визуализация данных для киноманов... Статья отличная, детально рассказывает, как решить поставленную задачу. Если вкратце, то там рассказывается о том, как спарсить "весь" Кинопоиск или IMDb и визуализировать полученные данные красивым графом. И мне показалось, что "в интернете кто-то не прав" (С). Ведь и вправду, автору потребовалось "2-3 дня" для сбора данных, а это непозволительно много, ведь, как известно, "время - деньги".

Оставлю визуализацию специалистам, а я расскажу, как можно быстро собрать нужные данные для решения этой задачи.

Парсить будем IMDb, поэтому анализируем сайт. Начинать парсинг было решено со страниц рейтингов фильмов, и оттуда уже "углубляться". По каждому фильму нужно собрать название, дату, жанры, страны, режиссера и рекомендации (People who liked this also liked...). При визуализации данных рекомендации нужны будут для постоения связей, а нам они пригодятся во время парсинга для поиска новых фильмов. Т.е. нужно будет заходить в каждый рекомендованный фильм, получать вышеперечисленные данные, заходить в его рекомендации, и так далее, по кругу.

Итак, теперь, когда определен алгоритм работы, составляем пресет. Используем Net::HTTP Net::HTTP - его будет достаточно. Сначала нам нужно из начальных списков получить ссылки на фильмы и подставить их в запросы. Т.к. это по сути разовое действие, то лучше парсинг ссылок сделать в шаблонизаторе, чтобы исключить лишнюю нагрузку во время парсинга. Подстановка на следующий уровень осуществляется с помощью инструмента tools.query.add().
Код:
[% IF query.lvl == 0;
    top = p1.data.match('<td class="titleColumn">[^<]+<a href="([^"?]+)', 1);
    FOREACH link IN top;
        tools.query.add('http://www.imdb.com' _ link);
    END;
END %]
Далее в пресете прописываем регулярные выражения для получения нужной информации. IMDb меняет язык в зависимости от заголовков браузера с которого он запрашивается. Поэтому, чтобы исключить ситуацию, когда результаты на разных языках (т.к. при парсинге будут использоваться прокси разных стран), смотрим в браузере, как IMDb определяет язык. И видим, что это Accept-Language. Поэтому прописываем этот заголовок в пресете:
Код:
Accept-Language:en-US,en;q=0.9
Также, чтобы исключить возможные баны и ошибки, задаем Good status и Check content.

Т.к. мы планируем выводить результат в JSON, то в Формате результата прописываем формирование нужной структуры данных. А также не забываем подставлять ссылки на рекомендации в запросы.
Код:
    result = {};
    result.id = p1.id;
    result.name = p1.name.collapse;
    result.rating = p1.rating.remove('^none$');
    result.director = p1.director.remove('^none$');
    result.date = p1.date.remove('^none$');
    result.genres = [];
    FOREACH item IN p1.genres;
        result.genres.push(item.name);
    END;
    result.countries = [];
    FOREACH item IN p1.countries;
        result.countries.push(item.name);
    END;
    result.rec = [];
    FOREACH item IN p1.rec;
        result.rec.push(item.id);
        tools.query.add('http://www.imdb.com/title/' _ item.id _ '/');
    END;

    result.json _ ",\n";
Обязательно включаем Уникализацию запросов, чтобы избежать повторных заходов на уже обработанные страницы.

В целом на анализ сайта и составление пресета у меня ушло 20 мин. Плюс еще 10 минут на тесты и отладку. Итого за полчаса мы имеем готовый пресет. Запускаем в работу:)
ecaoq_180220140515.png

Как видно на скриншоте, парсинг запущен в 300 потоков. Средняя скорость более 2000 запросов в минуту.

В итоге, спустя чуть менее, чем полтора часа была получена база результатов для 182 тысяч фильмов:
A-Parser__Advanced_SE_Parser_&_Analyze_tool_-_Google_Chrome_2018-02-20_14.11.08.png


Готовый пресет: https://a-parser.com/resources/268/
Готовая база: https://files.a-parser.com/IMDB_base_feb-20_11-30-53.txt (46,9 Мб)
  • Like
Реакции: venila и dankamaster
Автор
Support
Просмотры
16
Первый выпуск
Обновление

Рейтинги

5,00 звёзд Оценок: 1

Ещё ресурсы от Support

Назад
Верх