您花了多少时间看电影?

想法的出现


最近,我去拜访朋友,我们选择了一部电影,而我作为被烧毁的电影迷(实际上并不是那么被烧毁)拒绝了所观看的一切。 他们问我一个合乎逻辑的问题,但是你为什么不看呢? 我说过我正在进行电影搜索,并且我看了我看过的每部电影,无论是通过评分还是在观看时打勾。 然后我想到一个问题,但是我花了多少时间在电影上? 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次迭代),并认为它们可疑。 他是对的! 但是我也建议使用此选项,然后继续进行B计划。

计划B-更换代理如手套


选择了第一台提供用于获取IP代理的API的服务器(我没有做广告的任何服务,从Google获得了前两个链接),将其弄歪了,然后继续编写主要代码。 一个小时后,当我接近完成时,我被API提供的服务器阻塞了! 我必须将其更改为另一个,每半小时产生一个固定的列表,对于我的任务来说已经足够了。 但是,如果列表突然结束,则可以返回上一个选项(它们每24小时发布1​​0-24个代理)。

 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") 

将所有这些结合在一起(最后,我将提供指向github和最终版本的链接),我可以算出花在电影上的时间是一件很棒的事情。 他收到了珍贵的电话号码:“您浪费了84542分钟或1409.03小时或58.71天。”

徒劳地花费时间


其实并非徒劳。 这项任务对至少某人来说很有趣,尽管几乎没有必要。
现在我可以告诉大家,我生命中的近两个月都在看电影!

如果有人也会对自己获得这样的“重要”统计数据感兴趣,只需复制您的个人资料ID并使用此参数启动项目,如果您可以轻松地在评论中放弃结果,那么我对电影迷或初学者很感兴趣。

源代码链接

PS:我也很高兴听到有关改进代码的提示,因为我在python上写的很少,甚至还没有完全理解语法。

Source: https://habr.com/ru/post/zh-CN430978/


All Articles