Возникновение идеи
Недавно был в гостях у друзей и мы выбирали фильм, а я как прожжённый киноман (на самом деле, не то чтобы прям прожжённый) отбраковывал всё как просмотренные. И мне задали логичный вопрос, а что ты вообще не смотрел? На что я рассказал, что веду кинопоиск и каждый фильм, которые посмотрел отмечаю либо оценкой, либо просто галочкой, что просмотр состоялся. И тут в голове у меня возник вопрос, а сколько я вообще времени то потратил на фильмы? В Steam есть удобная статистика по игре, а по фильмам ничего такого нет. Вот и решил я заняться данной идеей.
Что там с реализацией?
Я уже несколько лет разрабатываю на ASP.NET и привык к C#, сначала на нём и хотел написать данную утилиту, но тут возникла проблема с тяжеловесным окружением и, так как я немного знаком с Python, именно к его помощи я прибегнул.
А где взять данные?
И вот тут я столкнулся с первой проблемой. Я наивно предполагал, что у кинопоиска есть официальное публичное API и какая-нибудь бесплатная версия. Но ничего такого я не нашёл. Есть возможность запросить через техподдержку, но и там выдают только за n-ую сумму, а я писал это для себя и никак не хотел платить за это.
Естественно, пришлось рассматривать вариант парсинга страниц и именно на нём я и остановился.
У каждого в профиле есть список просмотренных фильм с небольшим описанием, которое включает продолжительность картины. Таким образом я могу получить всего несколько страниц (У меня 762 фильма и необходимо было получить всего 17 страниц) и рассчитать потраченное время.
Сказано — сделано.
class KinopoiskParser:
def __init__(self, user_id, current_page=1):
self._user_id = user_id
self._current_page = current_page
self._wasted_time_in_minutes = 0
def calculate_wasted_time(self):
while True:
film_list_url = f'https://www.kinopoisk.ru/user/{self._user_id}' f'/votes/list/ord/date/genre/films/page/{self._current_page}/#list'
try:
film_response = requests.get(film_list_url).text
except BaseException:
proxy_manager.update_proxy()
continue
user_page = BeautifulSoup(film_response, "html.parser")
is_end = kinopoisk_parser._check_that_is_end_of_film_list(user_page)
if is_end:
break
wasted_time = self._get_film_duration_on_page(user_page)
self._wasted_time_in_minutes += wasted_time
print(f'Page {self._current_page}, wasted time {self._wasted_time_in_minutes}')
self._move_next_page()
def get_wasted_time(self):
return self._wasted_time_in_minutes
def _move_next_page(self):
self._current_page += 1
@staticmethod
def _get_film_duration_on_page(user_page):
try:
wasted_time = 0
film_list = user_page.findAll("div", {"class": "profileFilmsList"})[0].findAll("div", {"class": "item"})
for film in film_list:
film_description = film.findAll("span")
if len(film_description) <= 1:
continue
film_duration_in_minutes = int(film_description[1].string.split(" ")[0])
wasted_time = wasted_time + film_duration_in_minutes
return wasted_time
except BaseException:
print("Something went wrong.")
return 0
@staticmethod
def _check_that_is_captcha(html):
captcha_element = html.find_all("a", {"href": "//yandex.ru/support/captcha/"})
return len(captcha_element) > 0
@staticmethod
def _check_that_is_end_of_film_list(html):
error_element = html.find_all("div", {"class": "error-page__container-left"})
return len(error_element) > 0
Но уже на этапе отладки я столкнулся с проблемой, что кинопоиск блокирует запросы (примерно, на 4 итерации) и считает их подозрительными. И он ведь прав! Но такой вариант я тоже предполагал и перешёл к плану Б.
План Б — меняем прокси как перчатки
Взяв первый попавшийся сервер, который предоставляет API для получения ip proxy (не рекламирую никакие сервисы, взял первые две ссылки из гугла), криво прикрутил его и продолжил писать основной код. И уже через час, когда я был близок к завершению меня заблокировал и сервер, которые предоставляет API! Пришлось сменить его на другой, который выдаёт фиксированный список, каждые полчаса, для моей задачи этого достаточно. Но если вдруг кончится список, можно вернутся к предыдущему варианту (они выдают каждые 24 часа где-то 10-20 proxy).
class ProxyManager:
def __init__(self):
self._current_proxy = ""
self._current_proxy_index = -1
self._proxy_list = []
self._get_proxy_list()
def get_proxies(self):
proxies = {
"http": self._current_proxy,
"https": self._current_proxy
}
return proxies
def update_proxy(self):
self._current_proxy_index += 1
if self._current_proxy_index == len(self._proxy_list):
print("Proxies are ended")
print("Try get alternative proxy")
proxy_ip_with_port = self._get_another_proxy()
print("Proxy updated to " + proxy_ip_with_port)
self._current_proxy = f'http://{proxy_ip_with_port}'
return self._current_proxy
proxy_ip_with_port = self._proxy_list[self._current_proxy_index]
print("Proxy updated to " + proxy_ip_with_port)
self._current_proxy = f'http://{proxy_ip_with_port}'
return self._current_proxy
@staticmethod
def _get_another_proxy():
proxy_response = requests.get("https://api.getproxylist.com/proxy?protocol[]=http", headers={
'Content-Type': 'application/json'
}).json()
ip = proxy_response['ip']
port = proxy_response['port']
proxy = f'{ip}:{port}'
return proxy
def _get_proxy_list(self):
proxy_response = requests.get("http://www.freeproxy-list.ru/api/proxy?anonymity=false&token=demo")
self._proxy_list = proxy_response.text.split("\n")
Соединив всё это вместе (в конце приведу ссылку на гитхаб с конечной версией), я получил отличную штуку для подсчёта времени потраченного на фильмы. И получил заветное число, тадам: «You wasted 84542 minutes or 1409.03 hours or 58.71 day».
Зря потратил время для подсчёта зря потраченного времени
На самом деле, не зря. Задача была интересная, хоть и вряд ли нужная хоть кому-то.
Да и теперь я могу всем говорить, что, почти, два месяца своей жизни я занимался просмотром кино!
Если кому-то будет тоже интересно получить такую «важную» статистику для себя, просто скопируйте id своего профиля и запустите проект с этим параметром и если несложно скиньте в комментарии результат, мне интересно «киноман» я или любитель начинающий.
Ссылка на исходный код
P.S. Также буду рад услышать советы по улучшению кода, так как на питоне писал очень мало и даже синтаксисом владею не в полной мере.
Комментарии (70)
aleks_raiden
25.11.2018 16:22+2Как инструмент для прокачки скилла программирование — все отлично )
Но как я понимаю, эти цифры вы могли просто посмотреть в своем профиле на кинопоиске.
P.S. Я со своими 3 294 фильмами (а реально больше, не всегда обновляються те, что уже вышли в прокат) получается, не просто заядло-прожженый, а капец как )))alados Автор
25.11.2018 16:27Чуть выше уже ответил, я считал именно по фильмам, потому что по сериалам получается немного некорректно. А ещё я не заметил этой плашки раньше=)
Andriy1218
26.11.2018 15:36Вы походу очень не любите фильмы, раз ваша средняя оценка 1.000. Зачем же вы их столько смотрите?)
aleks_raiden
26.11.2018 15:56Это скорее мое отношение к оценкам ) Мне абсолютно не интересны оценки других, я принципиально смотрю все фильмы, а моя личная оценка — никому не интересна. Поэтому кинопоиск я использую только для записи какие именно фильмы просмотрены и все.
Andriy1218
26.11.2018 17:24Там можно просто обозначать, что фильм просмотрен(без оценки). Просто так вы на ровном месте понижаете всем фильмам оценку. Хотя я слышал, что единицы в последнее время не учитываются в рейтингу, но это не точно. Я такой аккаунт принял бы за бота. Да и возможно в настройках можно настроить параметры конфиденциальности.
MiSaf
25.11.2018 16:23А теперь сравните полученную вами цифру с тем, что считает кинопоиск автоматически. Там такая статистика есть на вкладке "Оценки" в профиле.
Оценки в цифрах всего записей 1166 фильмы 1136 сериалы 21 короткометражки 9 время 111 д 14 ч 22 мин
alados Автор
25.11.2018 16:26На самом деле, я не смог найти такую инфу у них, но это из-за невнимательности.
Но всё-таки мой подсчёт тоже имеет смысл. Я считал только по фильмам, а на кинопоиске вместе с сериалами и это вызывает некоторую проблему. Часто из сериала я смотрю 1-2 сезона, а он считает, на сколько я понял, по всем существующим сезонам.aleks_raiden
25.11.2018 17:06Ну логика в этом есть — это нельзя считать за полностью просмотр, поэтому или не отмечать или вот будут погрешности. Стоило бы добавить им еще вариант оценки «неполный просмотр» как раз в применимости к сериалам
Chugumoto
26.11.2018 11:08ну так это получается проблема самого кинопоиска и как вариант нужно им куда-нибудь об этом сообщить?
на лостфильме например статистика нормально ведется не только по сезонам, но и по сериям…Andriy1218
26.11.2018 15:47Вряд ли они как-то прореагируют на такое замечания. Я им пару раз писал всякие небольшие (и как по мне очень полезные) предложение по новому функционалу и корректировки существующего. Ни по одной заявке не было больше никаких записей, кроме первоначальной про регистрацию моего предложения в базе. Да я и сам замечаю, что за последние несколько год заметного добавления функционала не было.
Хотя все это субъективно и я могу ошибаться.
lain8dono
25.11.2018 16:29You wasted 84542 minutes or 1409.03 hours or 58.71 day
Интересно, это много или мало? У меня где-то 200 суток аниме, но у меня нет ощущения, что я прям всё смотрел.
alados Автор
25.11.2018 16:35Вот мне тоже интересно. Вроде в комментариях говорят, что мои 762 фильма это самое начало восхождения к топу=)
wlr398
25.11.2018 16:41У всех свои пристрастия. Кто-то по книге каждый день читает. Кто-то каждый день марафонскую дистанцию бегает. Или всё свободное время игры гоняет. Или все выходные матан и хаскель.
Если нравится и никому не доставляет неприятностей, то в чём проблема…alados Автор
25.11.2018 16:44Абсолютно согласен, мне просто было интересно=)
Я вон чаще люблю в игры позалипать, когда есть хоть немного свободного времениaleks_raiden
25.11.2018 16:53Я для себя решил этот вопрос вторым монитором, на котором можно смотреть фильм ) Тем более достаточно много фильмов, которые можно смотреть вполглаза )
alados Автор
25.11.2018 17:22У меня так не получается, хотя тоже имею два монитора.
Многозадачность это для меня слишком сложная штука=)
shalm
26.11.2018 07:50меня хватает на один — два фильма в месяц, считаем 20 в год, штук 600 за 30 лет, соизмеримо с Вашей цифрой, при том что я себя киноманом не считаю
alados Автор
26.11.2018 07:56Я стараюсь смотреть каждую неделю по фильму, хотя далеко не всегда выходит
wlr398
26.11.2018 09:18Надо разделять просто развлечение и хобби. У тех, кто посмотрел много тысяч фильмов, это скорее всего хобби. Когда кроме просмотра изучаются материалы о съёмках, об актёрах, режиссёрах, жанрах, читаются всякие киношные форумы. Да и фильмы смотрятся не только те, что в кинотеатрах выходят и сериальный мейнстрим, а начиная с немого кино, снятого более 100 лет назад, артхаус всякий малопопулярный.
Причём хорошие, понравившиеся фильмы пересматриваются, может быть даже десятки раз. Поэтому надо вносить поправочный коэффициент :)
SvyatoslavMC
25.11.2018 17:05Когда LostFilm обновил сайт, там добавили подсчёт времени по сериям, т.е. можно отметить часть сезона даже. За 5 лет у меня набежало 96 дней, например.
helg1978
25.11.2018 17:09myshows.me тоже подсчитывает, удобно если не только лостфильм смотришь.
у меня 154 дня :(SvyatoslavMC
25.11.2018 17:12Меня огорчает только то, что если бы я всё это посмотрел в оригинале, то мой английский был бы на много лучше :D
alados Автор
25.11.2018 17:23А получается смотреть в оригинале? У меня страх, что ничего не пойму и придётся одну серию смотреть по несколько раз. Поэтому смотрю всё с переводом=(
SvyatoslavMC
25.11.2018 17:30Потеря информации заметно большая. Я решил тренироваться на аудиокнигах/подкастах, а сериалы оставить в покое. С субтитрами хорошо заходит, но нет ощущения комфортного просмотра, да и навыки аудирования это не улучшает, поэтому тоже исключил.
alexey-m-ukolov
25.11.2018 17:47+1Я именно так язык и подняд до хорошего уровня. Сначала смотрел с русскими субтитрами, потом перешёл на английские, потом совсем от них отказался. Лет пять всё это заняло. Ну а какая это прелесть — не зависеть ни от сроков выхода перевода, ни от его качества — это словами не описать.
helg1978
25.11.2018 18:06мне помогла подписка на Netflix.
Он настолько классный и удобный, что смотреть что-то в браузере с рекламой ставок на спорт никакого желания нет.marataziat
25.11.2018 19:45Просто баньте через ublock origin, и установите бан лист для рунета и все будет хорошо! Если не дай бог реклама откроется просто через девтулзы браузера найдите источник и забаньте :) Я так пару раз забанил теперь рекламы вообще нет!
aamonster
25.11.2018 20:19Добрые люди советуют смотреть с субтитрами, настроив для них отставание на несколько секунд.
marataziat
25.11.2018 19:36Что если собирать статистику с проигрывателя сайта прямо в браузере? Мало ли на какую страницу с фильмом ты зашел, другое дело сколько ты посмотрел! Помоему можно сделать webextension для этого :) Данные о просмотренном времени на фильм можно хранить в browser.localStorage и потом делать красивый дашборд с графиком :)
alados Автор
25.11.2018 20:59Это тоже очень относительная штука. Я, например, очень часто скачиваю фильм и смотрю на телевизоре или использую PS4. Поэтому такие вещи уже очень тяжело оптимизировать=)
Demiurge067
25.11.2018 20:58Даже не знаю, для чего я это пишу, но статистика за 5 лет такая: 1356 фильмов. 142396 минут. 2373 часа. 98 суток.
Да, плюсом добавил скачанные торренты. Люблю побаловать себя 3D и качественным HD.
Жуть, сколько потрачено времени… С другой стороны — не все же время работать)))marataziat
26.11.2018 08:090.7 фильмов в день? Очень мощно!
Demiurge067
26.11.2018 10:16Да, многолетняя сложившаяся традиция — прихожу домой с работы, решаю текущие вопросы, включаю киношку. Сериалы иногда заходили по две-три серии, правда, надоедали быстро)))
facetus
25.11.2018 22:04А как можно ориентироваться только на один ресурс? Вы что только там фильмы смотрите? Я за всю жизнь с сотни разных источников смотрел — как посчитать? Да никак =)
Так что всё это лишь данные с аккаунта на сайте…Andriy1218
26.11.2018 15:53Ну вообще-то на КиноПоиске фильмы почти никто не смотрит(хотя в последнее время там появилась такой функционал для части фильмов и сериалов). КиноПоиске это русскоязычный аналог imdb. То есть это база фильмов, сериалов и прочего.
dmxrand
25.11.2018 23:36И без скрипта скажу что не смотрел Колобаху, Ятинсотэстс, Космический ворс. С вероятностью 80% не смотрел Zero, Zero 2, Zero 3, Занесло.
FeNUMe
25.11.2018 23:43
И это только сериалы и я еще не всё туда вносил. Думаю фильмов наберется еще на такую же цифру.
werwolfby
25.11.2018 23:55Удивлён, что никто не рассказал про http://www.trakt.tv
Есть отличный плагин для коди, много лет пользуюсь, и там вся статистика есть.
artemisia_borealis
26.11.2018 02:00Почти off.
А я вот, наоборот долго терял интерес к худ. фильмам и несколько лет назад потерял его окончательно. Сейчас могу оценить просмотры как 1-3 фильма в год.
Трудно представить, что может меня даже не заставить, а просто соблазнить смотреть художественное кино. Вот неинтересно совсем.
Интересно понять мотивацию тех, кто в таких, по-моему астрономических, дозах смотрит кино. Неужели там столько стоящего?
Не говорю о том, что вот, мол, можно было бы потратить время на что-то более полезное. Это чушь. Как раз если интересно, то, значит, и полезно. Но вот почему интересно?sim31r
26.11.2018 03:19Наверное что-то связанное с получением новой информации, любопытство и любознательность.
Demiurge067
26.11.2018 10:20У меня, возможно, возрастная деградация. Когда все «полезное» сделано, ну там — построить тёщу, посадить печень и т.п. Да и как отказать ребенку, который запал на «Склифа»???))) Так и бывает)))
ivansmith
26.11.2018 13:15У меня тоже самое. Не смотрю художку вообще, хотя раньше смотрел. (Сейчас может 1-2 фильма в год в кинотеатре). Не интересно, сюжеты банальные и жалко на это время тратить…
Но смотрю Top Gear/Grand Tour с оригинальной дорожкой :)
LoadRunner
26.11.2018 09:20А стоит ли учитывать время, потраченное на обсуждение увиденного?
У нас с женой есть привычка ставить фильм на паузу и делать очередной фейспалм от сюжетной дыры или ещё какой глупости. Ну или просто обсудить что-либо, просто поговорить на тему, связанную с увиденным, предположить возможные сюжетные повороты, вот это вот всё. И просмотр одного фильма может растянуться часов на 5. А то и больше — Бен Гура мы сутки смотрели.
P. S. В качестве мотивации просмотра фильмов как раз подходит совместный досуг с женой :)alados Автор
26.11.2018 10:53Не у всех есть жена=)
Я вот смотрю фильмы в гордом одиночестве и обсуждать всё приходится с самим собой
urmaul
26.11.2018 17:34Интересно было бы учесть и оценки на Кинопоиске. Хотя бы разделить на два числа: время фильмов, которые понравились и которые не понравились.
alados Автор
26.11.2018 17:36Можно и конкретно по оценкам, это несложно сделать. Если буду делать версию V2, обязательно, внедрю эту функцию=)
SvyatoslavMC
26.11.2018 20:06Тогда больше никто не скажет, что время, проведённое с удовольствием, не считается потерянным :D
akokarev
Моя бабушка 3 раза посмотрела всю Санта-Барбару. Как посчитать сколько лет жизни ушло на просмотр?
GrigorGri
Ну, это легко. Гуглим Санта-Барбара продолжительность. Находим что это 66 дней. Умножаем на 3 -> 198 дней. В итоге ни одного года (чистого времени, без учета времени на сон и т.д.)
wlr398
Это как раз не сложно. 2137 серий по 45 минут. То есть всего 67 дней, если не ошибаюсь в подсчётах.
А как у автора заметки 762 это довольно мало. У меня 4447 на данный момент. Чтобы стать IMDB top 1000 voter надо ориентировочно 15000-20000. Честно говоря, не представляю, как можно столько осилить, если честно, не пытаясь накручивать.
alados Автор
Вот мне как раз и было интересно услышать другие числа. А то большинство друзей не ведут никаких списков и, почти, всех поражает число 762 просмотренных фильма.
VIPDC
И вы и GrigorGri забыли существенный момент для сериалов — реклама.
По этому смело добавляем по 15 минут рекламы на каждую серию итого + 32005 минут (534,25 часов, 22,3 дня). Умножим на три 66,9 дней.
Chugumoto
откуда рекламе взяться? здесь вам не ТВ :)
SvyatoslavMC
Вероятно, бабушка смотрела именно по ТВ :)
GrigorGri
Это зависит от того, что считать за время потраченное на просмотр. Все таки просмотр рекламы и просмотр сериала это разные вещи. Даже неизвестно, оставалась ли бабушка чтобы посмотреть рекламу или занималась чем нибудь другим.
tartarelin
Может смотрят фильмы на скорости 1.5 или больше