Combien de temps avez-vous consacré aux films?

L'émergence des idées


Récemment, je rendais visite à des amis et nous avons choisi un film, et moi, en tant que cinéphile brûlé (en fait, pas si directement brûlé), j'ai tout rejeté comme vu. Et ils m'ont posé une question logique, mais qu'est-ce que vous n'avez pas regardé du tout? À laquelle j'ai dit que je fais une recherche de film et que je regarde tous les films que j'ai regardés, soit par note, soit juste par une coche que le visionnement a eu lieu. Et puis une question s'est posée dans ma tête, mais combien de temps ai-je passé sur les films? Steam a des statistiques pratiques pour le jeu, mais rien pour les films. J'ai donc décidé d'aborder cette idée.



Qu'en est-il de la mise en œuvre?


Je développe sur ASP.NET depuis plusieurs années et je suis habitué à C #, au début, je voulais écrire cet utilitaire dessus, mais il y avait un problème avec un environnement lourd et, comme je suis un peu familier avec Python, j'y ai eu recours.

Et où obtenir les données?


Et là, je suis confronté au premier problème. J'ai supposé naïvement que la recherche de films avait une API publique officielle et une sorte de version gratuite. Mais je n'ai rien trouvé de tel. Il y a une possibilité de demander par le biais du support technique, mais même là, ils ne donnent que pour le nième montant, et j'ai écrit cela pour moi-même et je ne voulais pas payer pour cela.

Naturellement, j'ai dû envisager l'option d'analyser les pages, et c'est là-dessus que je me suis arrêté.

image

Tout le monde dans le profil a une liste de films regardés avec une petite description qui inclut la durée de l'image. De cette façon, je ne peux obtenir que quelques pages (j'ai 762 films et il fallait seulement 17 pages) et calculer le temps passé.

Aussitôt dit, aussitôt fait.

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 

Mais déjà au stade du débogage, je suis tombé sur un problème que la recherche cinéma bloque les requêtes (environ 4 itérations) et les considère suspectes. Et il a raison! Mais j'ai également suggéré cette option et je suis passé au plan B.

Plan B - changer les procurations comme les gants


En prenant le premier serveur qui fournit une API pour obtenir un proxy IP (je ne fais de la publicité pour aucun service, j'ai pris les deux premiers liens de Google), je l'ai vissé de travers et j'ai continué à écrire le code principal. Et une heure plus tard, alors que j'étais presque terminé, j'ai été bloqué par le serveur que l'API fournit! J'ai dû le changer en un autre, qui produit une liste fixe, toutes les demi-heures, pour ma tâche, cela suffit. Mais si la liste se termine soudainement, vous pouvez revenir à l'option précédente (ils émettent 10 à 24 procurations toutes les 24 heures).

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

En combinant tout cela ensemble (à la fin, je donnerai un lien vers le github avec la version finale), j'ai eu une excellente chose pour compter le temps passé sur les films. Et il a reçu le numéro chéri, tadam: "Vous avez perdu 84542 minutes ou 1409.03 heures ou 58,71 jours."

En vain passé du temps à compter en vain passé du temps


En fait, pas en vain. La tâche était intéressante, quoique à peine nécessaire, pour au moins quelqu'un.
Et maintenant, je peux dire à tout le monde que pendant près de deux mois de ma vie, j'ai regardé un film!

Si quelqu'un souhaite également obtenir des statistiques "importantes" pour lui-même, copiez simplement l'ID de votre profil et démarrez le projet avec ce paramètre et si vous pouvez facilement ignorer le résultat dans le commentaire, je suis intéressé par un "fan de cinéma" ou un débutant.

Lien du code source

PS Je serai également heureux d'entendre des conseils sur l'amélioration du code, car j'ai très peu écrit sur python et je ne comprends même pas complètement la syntaxe.

Source: https://habr.com/ru/post/fr430978/


All Articles