Python3でSeleniumを利用してwebサイトから情報抽出
映画が好きでちょくちょく映画館に行くのですが、それほど頻度が多くないので見たい映画を見逃すことがありました。
鳥取県在住なので映画館はほぼ候補がなく、1つだけ確認しておけばいいのでどうせなら自動化してやろうと思いスクリプトを自作してみました。
Python3とSeleniumを使ってブラウザを自動操作し、映画館の上映情報を取得するというスクリプトの備忘録兼まとめ記事です。
Seleniumのインストール
SeleniumはプログラムからWebブラウザを操作するツールです。Webアプリ開発でテストに利用したり、Webから情報を抽出して利用するWebスクレイピングで利用されます。今回はpython3から動かして利用しました。
pipでインストールできますので導入はとても簡単です。以下コマンドでパッケージをインストールしてください。
pip install selenium
WebDriverをインストール
SeleniumでWebブラウザを操作するために必要なソフトをインストールします。今回はChromeを利用しました。2018/09/27現在最新のドライバー2.42を利用すればすべてのバージョンのChromeを操作できるようです。リンク先のDownloadsからたどっていけばダウンロードできます。
ChromeDriver - WebDriver for Chrome
インストールしたら任意のディレクトリにドライバーを配置してください。配置したパスはpythonのコードで指定するので覚えておきましょう。
Python3のソースコード
以下が作成したPython3のスクリプトになります。
「Seleniumの設定」のところで"--headless"と指定しているのは、ブラウザをウィンドウで開かないようにしています。この指定をしないとスクリプトを実行する度に、Crhomeが起動します。Seleniumの動作を確認したいときはコメントアウトすると動きが分かりやすいです。
DRIVER_PATHに先ほどインストールしたChrome用WebDriverのパスを指定し、driver変数を用意してブラウザを操作しています。URLには情報を抽出したいWebサイトのurlを指定します。
実際にブラウザを操作しているのがメソッドfind_elements_by_css_selector()のあたりです。このメソッドはWebページのCSSセレクタを指定することで、任意の要素を取得することができます。最初の呼び出しでは上映スケジュールのボタンを取得してきてクリックすることで、上映映画の一覧を表示する動作をさせています(興味のある方は指定したURLにアクセスして週間上映スケジュールボタンを押してみてください)。CSSセレクタに何を指定するかはWebページを解析して判断する必要があります。ブラウザの開発者ツールなどを利用して解析してみましょう。
for文のところで上映映画のタイトルを取得してmessageに格納し、Line Notityで通知を送っています。Line Notifyについては以前の記事で紹介しているのでよろしければそちらをご覧ください。
doinaka-it-zakki.hatenablog.com
from selenium import webdriver import line_notify as ln DRIVER_PATH = "D:/driver/chromedriver.exe" URL = "https://www.smt-cinema.com/site/hiezu/index.html" # LINE notifyによる通知設定 lne = ln.LineNotify('LINEのAPIトークン', 'https://notify-api.line.me/api/notify') # Seleniumの設定 options = webdriver.chrome.options.Options() options.add_argument("--headless") driver = webdriver.Chrome(DRIVER_PATH, chrome_options=options) driver.get(URL)
elem_schedule_btn = driver.find_elements_by_css_selector("#schedule > ul > li") if len(elem_schedule_btn) > 1: elem_schedule_btn[1].click() movie_list = driver.find_elements_by_css_selector(".weekly > div") message = '' for movie_elem in movie_list: title = movie_elem.find_elements_by_css_selector(".weekly > div > div > div > p.title") message += title[0].text + '\n' # LINEに週間上映映画情報を送信 res = lne.send_message(message)
driver.close()
driver.quit()
無事に映画の上映リストを取得して、LINEに通知を送ることが出来ました。余談ですが私は毎日12:00に通知がくるようにスクリプトの定期実行を設定しています。
参考
PythonとSeleniumを使ったブラウザ自動操作 – 名古屋のWebシステム開発 iNet Solutions
SeleniumからHeadless Chromeを使ってみた
PythonでSeleniumを使ってスクレイピング (基礎)