映画にどれくらい時間を費やしましたか?

アイデアの出現



最近、私は友人を訪ねて映画を選びましたが、私は映画の熱烈なファン(実際には、やけどを負った映画ファンではない)として、見たものをすべて拒否しました。 そして彼らは私に論理的な質問をしましたが、なぜあなたはまったく見なかったのですか? 私は映画の検索を行っていると言いましたが、私は視聴したすべての映画を、評価によって、または視聴が行われたティックごとに視聴します。 それから私の頭の中に疑問が生じましたが、映画にどれくらいの時間を費やしましたか? 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から最初の2つのリンクを取得)、それをねじ込み、メインコードを書き続けました。 そして、1時間後、完成に近づいたとき、APIが提供するサーバーにブロックされました! 私はこれを30分ごとに固定リストを作成する別のリストに変更しなければなりませんでした。私のタスクではこれで十分です。 ただし、リストが突然終了した場合は、前のオプションに戻ることができます(24時間ごとに10〜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日を無駄にしました。」



無駄に費やした時間を無駄に数える



実際、無駄ではありません。 このタスクは、少なくとも必要ではありませんが、興味深いものでした。

そして今、私の人生のほぼ2ヶ月間、私は映画を見ていたことをみんなに伝えることができます!



誰かがこのような「重要な」統計の取得に興味がある場合は、プロファイルのIDをコピーしてこのパラメーターでプロジェクトを開始します。コメントの結果を簡単に破棄できる場合は、「映画ファン」または初心者に興味があります。



ソースコードリンク



PS pythonについてはほとんど書いておらず、構文についても完全には理解していないので、コードの改善に関するアドバイスも喜んで聞きます。



All Articles