Python と Selenium でスクレイピングのお勉強です。
Selenium は外部プログラムから Web ブラウザを操作することができる仕組みで、元々は Web アプリケーションのテスト自動化のためのツールだったようです。クリック、キー操作を外部アプリから操作できるので、技術的にはWebブラウザでできる全てのことを自動化するが可能です。
Selenium を使える言語としては Java, ruby, C#, Python, JavaScript のバインディングがあるのですが、Web を探してみるとスクレイピングの使い方としては Python + Selenium の情報量が圧倒的に多いため、Python で使ってみたいと思います。一般的には、Python + Selenium(ブラウザ制御) + Beautiful Soup(HTMLパーサ) の構成が多いようです。
概要をサラッと知るには Web よりも本のほうが良さそうなので、以下の書籍を買ってみました。
Pythonによるスクレイピング&機械学習 開発テクニック と みんなのPython です。みんなのPythonは 3 年くらい前に買ったものの読んでなかったやつなので、1つ前の第 3 版ですが、現在は新版の第4版が出ているようです。
本を参考に環境を構築します。
Python は pip というパッケージマネージャがあり、簡単にパッケージのインストールやアップデートができるようです。グローバルにインストールしなくても、ユーザローカルにライブラリをインストールできるのが便利です。
ということで、まずは python3 と pip をインストールします。その後、pip を使って selenium をインストールします。Ubuntu 18.04 には deb パッケージとしても python3-selenium というパッケージが用意されているのですが、最新を使いたいので pip でインストールしました。
$ sudo apt-get install python3 python3-pip $ pip3 install selenium
続いて、WebDriver の準備です。外部から制御できるような細工の入ったブラウザ本体のことです。Selenium の download のページにリンクがまとまっています。Firefox, Chrome などのオープンソースなものだけでなく、Internet Exproler, Safari, Opera のようなプロプライエタリなブラウザの webdriver もあるようです。Selenium が Web 自動テストのデファクトスタンダードになっているということでしょう。
WebDriver の中で異色なのが PhantomJS です。これはヘッドレス(画面のない)ブラウザで、ウインドウを表示せずにスクレイピングが可能です。開発中は画面のあるブラウザの方がデバッグしやすそうですが、安定したあとの実運用ではヘッドレスのほうが余計なウインドウが表示されないので便利そうです。リソースが許せばレンタルサーバ上でスクレイピングというのも可能かもしれません。メモリ, CPU をガッツリ使うので怒られそうですが。
環境が整ったので、本を見ながら見様見真似で作ってみたのが以下のコードです。
三井住友銀行に自動でログインするスクリプトです。コード中の USRID1, USRID2, PASSWORD を合わせればひとまず動作すると思います。
WebDriver には Firefox を使っています。geckodriver にパスが通っていれば、executable_pathの指定はいらないようです。
実行すると Firefox が立ち上がり、三井住友銀行のページを開いて、自動で契約者番号とパスワードを入力し、「ログイン」ボタンを押下します。見ていてちょっと面白いです。
#!/usr/bin/python3 from time import sleep from selenium import webdriver URL = "https://direct.smbc.co.jp/aib/aibgsjsw5001.jsp" USRID1 = "12345" USRID2 = "67890" PASSWORD = "1111" browser = webdriver.Firefox(executable_path="path/to/geckodriver") #browser = webdriver.Chrome() #browser = webdriver.PhantomJS() # open URL browser.get(URL) # enter browser.find_element_by_id("USRID1").send_keys(USRID1) browser.find_element_by_id("USRID2").send_keys(USRID2) # wait for input USRID2 sleep(1) # Password browser.find_element_by_id("PASSWORD").send_keys(PASSWORD) sleep(1) # Click login browser.find_element_by_name("bLogon.y").click(); #browser.quit()
sleep() でタイミング合わせているのが汚いですね。
待ち合わせがいまいちよくわかっていないので、時間でタイミングをとってしまいましたが、おいおいキレイにしていきたいと思います。
最後に browser.quit() を実行するとブラウザが閉じるのですが、開いたままのほうが Firefox の開発ツール(インスペクタなど)を使って入力フォームの id や name を確認できるので便利です。
こんな感じで作っていきたいと思います。