英語字幕DB作成への道_Flask編① (QuickStart)
seleniumで字幕データをダウンロードすることができるようになったので、
後はこれをAPIで呼び出せるようにしたい。
ということで前々から気になっていたFlaskを使ってみることにしました。
flask.palletsprojects.com
評判通りとてもシンプル!
今までDjangoを使っていたので、導入の簡単さに驚きました。
from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "<p>Hello, World!</p>"
今回はAPIは少ししか書かない予定なので、
これくらいシンプルなのがちょうどよいです!
今日も新しい発見ができてよかった!
英語字幕DB作成への道_Selenium編⑩ (selenium-wire)
DisneyPlusの動画を再生すると、ブラウザが裏側で .vtt という字幕ファイルをダウンロードします。
このファイルを手動でダウンロードするには、開発者ツールを開いて、Networkタブを開いて、
.vtt のURLをコピーして、wgetする必要があります。
なんとかこれを自動化したい。
ChromeOptionsやDesiredCapabilitiesで頑張ればなんとかできそうではあったのですが、
ChromeDriverのドキュメントがあまり親切ではなくて使い方がよくわかりませんでした。
そうしてネットの海をさまようことになったのですが、
そこで素晴らしいライブラリを見つけました。
それはselenium-wire
pypi.org
こんな感じで、Chromeがバックグラウンドで通信しているデータを取得できます。
from seleniumwire import webdriver # Import from seleniumwire # Create a new instance of the Chrome driver driver = webdriver.Chrome() # Go to the Google home page driver.get('https://www.google.com') # Access requests via the `requests` attribute for request in driver.requests: if request.response: print( request.url, request.response.status_code, request.response.headers['Content-Type'] )
※今回はこのrequest.urlが欲しかった
なんと素晴らしいライブラリでしょう。
無事に .vtt のURLを取得することができました。
英語字幕DB作成への道_Selenium編⑨ (ElementClickInterceptedException)
要素が画面上に表示されているのに、クリックすると ElementClickInterceptedException で失敗するときの解決方法が見つかりました。
それはexecute_script()。
Before
element = driver.find_element_by_css_selector('a.small-btn')
element.click()
After
element = driver.find_element_by_css_selector('a.small-btn') driver.execute_script('arguments[0].click();', element)
今のところ百発百中で成功しています。
なんなら element.is_displayed() が Falseでも成功します。
素晴らしい。
裏側の動きがどういう風に違うのかはわかりませんが、
一旦この例外が出たときはexecute_script()を使っていくことにします。
解決策がみつかってよかった!
英語字幕DB作成への道_Selenium編⑧ (explicit_waitの一本化)
下記の通り、waitの処理を一本化してみました!
def find_element(driver, *args, **kwargs): element = WebDriverWait(driver, timeout=120).until( lambda d: d.find_element(*args, **kwargs) ) return element def find_elements(driver, *args, **kwargs): elements = WebDriverWait(driver, timeout=120).until( lambda d: d.find_elements(*args, **kwargs) ) return elements |python|< これで毎回explicit_waitのコードを書かずに済みます! 我ながら結構いいアイデアだと思います! ネットで検索したらもっといいアイデアが出てくるかもとは思いますが、 しばらくは安易に検索しないで、自分で色々アイデアを出して行きたいと思います。
英語字幕DB作成への道_Selenium編⑦ (Xpath関数)
今日は初めてXpathの関数を使いました。
//button[starts-with(@data-testid, 'season-') and contains(@data-testid, '-button')]
とても便利でよいのですが、ends-withもしくはmatchみたいな関数も欲しかったです。
starts-withとcontainsだけでもなんとかなるのですが、少しモヤっとしますね。
他にもいくつか関数があるようなので、機会があったら使ってみます!
developer.mozilla.org
今日も新しいことを学べてよかったです!