WSL (Windows Subsystem for Linux) の環境 (Ubuntu 16.04.4 LTS) にインストールされている Python を使い、Windows 側のウェブブラウザを操作してみます。
本ページでは、Windows側のウェブブラウザとして Firefox を利用します。
目次
1. はじめに
目的
まず、このページの一番の目的はこちらです。
ここが出発点です。具体的に何をしたいのかというのは、様々あるでしょう。
これを実現するためにまず考えるのは、
という方法なのではないでしょうか。
ここで言っているのは、HTTP(S)のプロトコルレベルから実装するわけではなく、「HTTP(S)通信を行うライブラリを使ってウェブサーバーとやり取りするプログラムを書く」くらいの意味です。この手のライブラリを使えば、HTTP(S)リクエストを送信する際に、宛先となるURLとパラメータだけ指定すれば、あとの通信処理自体はライブラリに任せることができます。
これにより、多少はラクができるわけですが、それでもプログラムを作るのは大変です。なぜなら、目的としているブラウザ操作によって、どんなURL(エンドポイントと言います)に、どんなパラメータが送信されているかを事前に解析しておき、それをそのままプログラムで記述しなければいけないからです。人間が操作する分には、「特定のフィールドに何か文字列を入力してボタンを押す」という単純な操作であったとしても、そこで実際に行われている処理はそれほど単純でもないのです(単純な場合もありますが)。
更に、ウェブサーバーから受け取ったレスポンスの中に含まれている JavaScriptの処理が実行されることを踏まえた結果を利用したい場合は、対応できません。
そのような状況であるため、プログラムでウェブブラウザの操作を自動化する際にも、普段ウェブブラウザが内部でやってくれている処理は、ウェブブラウザに任せることはできないだろうか? という発想が生まれます。
Selenium とウェブブラウザのドライバ
そんな想いに応えてくれるのが、Selenium というソフトウェアです。
Selenium
Selenium は、「ブラウザに対して、やって欲しい操作を命令することができるライブラリ」です。この命令は、WebDriver (API) という汎用的な仕様として策定されています。命令を送る通信プロトコルとしては、HTTP(S)を利用します。
参考
- WebDriver | W3C Recommendation 05 June 2018
- WebDriver の仕様
- Selenium – Web Browser Automation
- Selenium の公式サイト
- Selenium WebDriver
- Selenium の中の「Selenium WebDriver」プロジェクトページ
- Selenium – Downloads
- Selenium のダウンロードページ
- GitHub – SeleniumHQ/selenium: A browser automation framework and ecosystem.
- Selenium の GitHubページ
- selenium · PyPI
- The Python Package Index (PyPI) の Selenium 用パッケージページ
- Selenium with Python — Selenium Python Bindings 2 documentation
- Selenium の Pythonバインディング(ライブラリ) ドキュメント
ウェブブラウザのドライバ
主要なウェブブラウザは、この WebDriver (API) で規定された命令を受け取ってウェブブラウザを動かすための「ドライバ」プログラムを用意しています。
参考
- Firefox用ドライバ: GitHub – mozilla/geckodriver: WebDriver <-> Marionette proxy
- Chrome用ドライバ: ChromeDriver – WebDriver for Chrome
全体像
全体像としては以下のような関係になります(ウェブブラウザとしてFirefox を使う場合)。
例えば、プログラミング言語 Python を使って、ウェブブラウザに特定の操作を行いたいとします。
Python を使ってプログラムを書くわけですが、そのコードの中で Selenium が提供する Python用ライブラリを呼び出します。その時、予めダウンロードしておいたウェブブラウザのドライバプログラムファイルもコードの中で指定しておきます。
こうすることにより、このライブラリは、WebDriver (API) に従った方法でドライバプログラムに対して命令を送信し、ドライバがウェブブラウザを操作するという仕組みです。
※ 多くのウェブブラウザ用ドライバは、Webのプロキシ(代理人)サーバーとして実装されています。
2. 簡単なプログラムを書いてみる
Python プログラムを書いて WSL 内で実行し、Windows 10 上の Firefox を操作する例を紹介します。
環境
- Windows 10
- WSL (Ubuntu 16.04.4 LTS)
- WSL 内の Python v2.7.12
- Windows 上の Firefox
手順
(1) Selenium の Pythonバインディング(ライブラリ)をインストールする
WSL 内に、Python自体は既に入っていましたので、Selenium用パッケージをインストールします。
# 最初に Pythonのパッケージ管理ツールである pip をインストールしておきます。
sudo apt install python-pip
# seleniumパッケージをインストールします
pip install selenium
(2) Firefox用ドライバを用意する
Releases · mozilla/geckodriver · GitHub にアクセスし、geckodriver-v0.21.0-win64.zip
をダウンロードします(その時の最新版でよいと思います)。
ダウンロードしたファイルを解凍すると、geckodriver.exe
という実行ファイルが生成されました。
このプログラムは単独で実行することもできますが、今回は Pythonプログラム内から呼び出すことにします。
(3) プログラムを書く
Python のプログラムを書きます。
今回は main.py
というファイルに、以下を記述しました。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox(executable_path="/mnt/c/Users/foo/tmp/geckodriver-v0.21.0-win64/geckodriver.exe");
q = u"ワールドカップ 2018"
driver.get('https://www.google.com/search?q=%s' % (q));
このプログラムを実行すると、Firefox が立ち上がり、Google を使って “ワールドカップ 2018” というキーワードで検索を実行します。
簡単な解説
このファイルの文字エンコーディングが、UTF-8 であることを明示します。(エディタでも、UTF-8 でファイルを保存します)
# -*- coding: utf-8 -*-
seleniumモジュールから、webdriver というクラスをインポートします。
from selenium import webdriver
Firefox用ドライバファイルを指定して、Firefox WebDriver のインスタンスを生成します。
driver = webdriver.Firefox(executable_path="/mnt/c/Users/foo/tmp/geckodriver-v0.21.0-win64/geckodriver.exe");
ここでは、このインスタンスを使って、Google 検索を実行しています。
q = u"ワールドカップ 2018"
driver.get('https://www.google.com/search?q=%s' % (q));
(4) プログラムを実行する
では、WSL のターミナルからプログラムを実行します。
./main.py
すると、Firefox が立ち上がり、Google で検索が行われます。
ちなみに、リモートからブラウザが制御されていることが分かるように、アドレスバーのところにロボットのアイコンが表示されます。
Chrome の場合は、「Chrome は自動テスト ソフトウェアによって制御されています。」と表示されます。
注意点
プログラムから起動した Firefox を手動で閉じても、geckodriver.exe
のプロセスは消えませんでした。(Chromeドライバも同様でした)
3. おわりに
「ウェブブラウザで行う特定の操作を自動化したい場合には、Selenium が使えるよ」ということで、Selenium や WebDriver の簡単な説明や関係について書きました。
今回は紹介できませんでしたが、「フォームのあるページを表示して、各フィールドに文字列をセットしていき、サブミットボタンを押す」というようなこともできます。そういった例も、また紹介したいと思います。