Автор задач: Тамбовцева А.А.
Задание выполняется самостоятельно. При любых нетривиальных совпадениях в решениях задач все вовлечённые домашние работы будут оценены на 0 баллов. Свой ipynb-файл с решением необходимо прислать до дедлайна на почту allatambov@gmail.com.
Дана страница с описанием фильма «Не покидай...» на сайте КИНО-ТЕАТР.РУ: https://www.kino-teatr.ru/kino/movie/sov/4319/titr/.
Сайт, конечно, уступает Кинопоиску и подобным ресурсам, но, поскольку он некоммерческий, парсить его несложно, исходный код доступен, и ограничений нет.
Важно. Если вдруг сайт все-таки выдает страницу с капчей при выгрузке исходного кода через Python, можно сделать следующее: загрузить HTML-страницу по ссылке на Github. Это, конечно, не универсальное решение, просто упрощение жизни в контексте данного задания, про имитацию действия пользователя и копирование настроек браузера мы будем говорить отдельно.
Используя возможности библиотек requests
и BeautifulSoup
, извлеките из страницы название фильма и его рейтинг. Сохраните их в переменные film_name
(тип string
) и film_rating
(тип float
) соответственно.
### YOUR CODE HERE ###
Сохраните в список act_info
информацию об актёрах (в «сыром» виде, в виде объектов BeautifulSoup
), которая хранится на карточке актёра.
Для определённости – вот пример элемента такого списка:
<div class="actor_details">
<div class="actor_film_descript" id="role_16801">
<div class="film_name"><a href="/kino/acter/w/sov/4484/bio/" itemprop="url" title="Лидия Федосеева-Шукшина"><strong itemprop="name">Лидия Федосеева-Шукшина</strong></a></div>
<div class="film_role">Королева Флора — <span class="film_main_role">главная роль</span></div>
<div class="film_role_descript">жена короля Теодора</div>
<div class="film_rating"><span id="role_rating_16801"></span></div>
</div>
<div class="actor_film_screens"><a href="/kino/movie/sov/4319/foto/a4484/1162854/" title="Лидия Федосеева-Шукшина"><img alt="Лидия Федосеева-Шукшина" class="actor_film_img" src="/acter/photo/4/8/4484/pv_1162854.jpg" title="Лидия Федосеева-Шукшина"/></a></div>
</div>
Выберите только элементы с индексами от 0 до 33 включительно, сохраните изменения в том же списке. Если информация сгружена правильно, это все актёры без учета актёров дубляжа и каскадёров. Их труд очень ценен, особенно с учётом некоторых деталей съёмок, но для следующих задач нужен рейтинг, а его для актёров за кадром на сайте нет.
### YOUR CODE HERE ###
Напишите функцию get_personal()
, которая принимает на вход элемент списка act_info
и возвращает список из следующих характеристик:
role_16801
в примере выше);Лидия Федосеева-Шукшина
в примере выше);Королева Флора — главная роль
в примере выше, пустая строка, если её нет);жена короля Теодора
в примере выше, пустая строка, если его нет).Примените эту функцию ко всем элементам списка act_info
и создайте новый список списков L
такого вида:
[['role_16801', 'Лидия Федосеева-Шукшина',
'Королева Флора — главная роль', 'жена короля Теодора'],
['role_16800', 'Вячеслав Невинный',
'Король Теодор — главная роль', ''],
...]
Преобразуйте полученный список в датафрейм main
, присвойте столбцам названия id
, name
, role
, desc
.
Подсказка: если роль/её описание не найдены, используйте конструкцию try-except
, чтобы в случае ошибки сохранять просто пустую строку. Разумно использовать эту конструкцию два раза, один try-except
для роли, а второй – для её описания, так как необязательно эта информация отсутствует одновременно.
### YOUR CODE HERE ###
Дан список словарей, где каждый словарь содержит число лайков и дислайков, поставленных актёрам зарегистрированными пользователями сайта (просто так спарсить их из исходного кода не получится, значения обновляются динамически, это возможно, обсудим позже):
N = [{"id":"role_160325", "plus":"52", "minus":"2"},
{"id":"role_1928641", "plus":"25", "minus":"1"},
{"id":"role_1966145", "plus":"21", "minus":"1"},
{"id":"role_1973000", "plus":"21", "minus":"1"},
{"id":"role_1973001", "plus":"21", "minus":"1"},
{"id":"role_1973002", "plus":"23", "minus":"0"},
{"id":"role_1973003", "plus":"23", "minus":"1"},
{"id":"role_1973005", "plus":"23", "minus":"2"},
{"id":"role_1973007", "plus":"26", "minus":"1"},
{"id":"role_1973008", "plus":"20", "minus":"1"},
{"id":"role_1973010", "plus":"30", "minus":"4"},
{"id":"role_1973011", "plus":"32", "minus":"2"},
{"id":"role_2088754", "plus":"27", "minus":"2"},
{"id":"role_16800", "plus":"142", "minus":"4"},
{"id":"role_16801", "plus":"99", "minus":"23"},
{"id":"role_16803", "plus":"119", "minus":"12"},
{"id":"role_16802", "plus":"133", "minus":"7"},
{"id":"role_16804", "plus":"131", "minus":"4"},
{"id":"role_56008", "plus":"92", "minus":"10"},
{"id":"role_62460", "plus":"95", "minus":"4"},
{"id":"role_72744", "plus":"116", "minus":"3"},
{"id":"role_83813", "plus":"39", "minus":"2"},
{"id":"role_89473", "plus":"92", "minus":"20"},
{"id":"role_124124", "plus":"108", "minus":"7"},
{"id":"role_132138", "plus":"122", "minus":"2"},
{"id":"role_132139", "plus":"108", "minus":"5"},
{"id":"role_132140", "plus":"74", "minus":"3"},
{"id":"role_132141", "plus":"65", "minus":"6"}]
Создайте датафрейм numbers
со следующими столбцами: id
, plus
, minus
. Измените тип столбцов plus
и minus
на тип integer
.
### YOUR CODE HERE ###
Добавьте в полученный ранее датафрейм numbers
столбец rating
, который представляет собой рейтинг актёра, вычисляемый как разность между числом лайков и дислайков.
### YOUR CODE HERE ###
Объедините датафреймы main
и numbers
по id актёров, назовите объединённый датафрейм final
. Отсортируйте актёров по убыванию рейтинга, выберите первые 10 строк и выведите на экран.
Подсказка: для объединения датафреймов используйте метод merge()
(способ объединения в how
менять не нужно, здесь мы смотрим на общие элементы, а значение inner как раз соответствует пересечению множеств). Для сортировки строк используйте метод .sort_values()
.
### YOUR CODE HERE ###
В списке our_attempts
сохранены кортежи со следующей информацией:
Отсортируйте список our_attempts
по разнице между лайками и дислайками, от большего значения к меньшему, сохраните изменения в этом списке.
Подсказка: аргумент key
в функциях и методах для сортировки, плюс, lambda-функция.
our_attempts = [("role_16800", 21, 10, 11),
("role_16804", 22, 9, 13),
("role_16802", 17, 14, 3),
("role_132138", 12, 19, -7),
("role_16803", 22, 9, 13),
("role_132139", 27, 4, 23),
("role_124124", 22, 9, 13),
("role_56008", 29, 2, 27),
("role_16801", 18, 13, 5),
("role_89473", 16, 15, 1)]
### YOUR CODE HERE ###
Используя датафрейм final
и отсортированный список our_attemps
, выведите на экран:
имена актёров, входящих в топ 10, согласно значениям rating
, полученным по данным сайта;
имена актёров, входящих в топ 10, согласно значениям разницы между лайками и дислайками, полученным благодаря нашему скромному опросу.
Пример вывода списка:
Имя Фамилия 1
Имя Фамилия 2
Имя Фамилия 3
Имя Фамилия 4
Имя Фамилия 5
Имя Фамилия 6
Имя Фамилия 7
Имя Фамилия 8
Имя Фамилия 9
Имя Фамилия 10
Если вам категорически не нравится полученный рейтинг или у вас осталось что сказать про парсинг, выскажитесь :)