LoginSignup
25
30

More than 5 years have passed since last update.

Seleniumに入門してみた。 Pythonでマルチスレッドのアクセス

Last updated at Posted at 2018-02-05

DevOpsやCD/CIに欠かせないブラウザでの自動テストのツール Selenium で、複数のウィンドから同一サイトを順次アクセスするツールを作ってみました。

概要

このツールを動作させた時のイメージは次の画像の様になります。 真ん中下のターミナルでPythonのSeleniumのWebDriverが動作しています。 そして、8個のブラウザ画面は、Pythonのプログラムから制御される、FireFoxブラウザで、それぞれ並行動作するスレッドで順番にサイトをアクセスしていきます。

Selenuim_test.gif

この自動テストのためのSelenium API のPythonコードを書いた備忘録です。

Selenium のインストール

Selenuimの実行環境にはMacOSを利用しました。 MacOSへのSeleniumのインストール方法は、Pythonが動作する環境で、以下だけです。

pip install -y selenium

しかし、そう簡単に動作しないので、MacOSの場合、Pythonでバージョンを指定するためのpyenv, そして Python 3.6.0 をインストールするためのMacOSの前提パッケージを入れます。

brew install pyenv

そして、すでに導入済みのopensslを一旦削除して再度導入、pyenvでのコンパイルするための環境変数をセットして、インストールを実行する様にします。

brew uninstall openssl && brew install openssl && CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" pyenv install 3.6.2

参考資料: macOS High Sierra: ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib? https://github.com/pyenv/pyenv/issues/993

それから、 zlibが必要なのですが、 brew install ではなく、次のコマンドを利用します。詳しくは 参考資料のstackoverflow.com を参照してください。

xcode-select --install

参考資料: https://stackoverflow.com/questions/23749530/brew-install-zlib-devel-on-mac-os-x-mavericks

ブラウザのドライバをインストール

FireFoxのドライバ

FireFoxのドライバは、geckodriver で、GitHub https://github.com/mozilla/geckodriver/releases からダウンロードできます。 アーカイブを解いたら、/usr/local/binへ置いておきます。

$ sudo cp geckodriver /usr/local/bin
$ sudo chmod +x /usr/local/bin/geckodriver 

Chromeのドライバ

こちらは、https://sites.google.com/a/chromium.org/chromedriver/ から入手できます。 同様に /usr/local/binへインストールします。

Seleniumのインストール

Pythonのバージョンが 3.6以上であることを確認して、

$ python --version
Python 3.6.2

Seleniumをインストールします。

$ pip install -y selenium

Pythonのプログラム

コメントを入れておいたので、コードの解説はコメントを読んでください。 このコードは、スレッドを8個立ち上げて、それぞれブラウザを立ち上げて、6個のウェブサイトを順にアクセスした後に、終了します。

FireFoxやChrome を一度に起動するので、メモリやCPUを消費しますので、RAMやCPUなど、資源を十分に搭載したMacで実行してください。 もしかしたら、ハングアップするかもしれないので、起動中のエディタなどのソフトは、実行前に保存しておいてくださいね。

このコードを実行すると、上記のGIF画像の様に、ブラウザが起動して、アクセスが進んでいきます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import threading
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0


th_objs = [] # スレッドの配列
driver = {}  # 各スレッドのwebdriverオブジェクト格納用

# ブラウザのサイズと表示位置
browsers = [
    { "size-x": "640", "size-y": "480", "pos-x": "0",    "pos-y": "0"},
    { "size-x": "640", "size-y": "480", "pos-x": "640",  "pos-y": "0"},
    { "size-x": "640", "size-y": "480", "pos-x": "1280", "pos-y": "0"},
    { "size-x": "640", "size-y": "480", "pos-x": "1920", "pos-y": "0"},
    { "size-x": "640", "size-y": "480", "pos-x": "0",    "pos-y": "480"},
    { "size-x": "640", "size-y": "480", "pos-x": "640",  "pos-y": "480"},
    { "size-x": "640", "size-y": "480", "pos-x": "1280", "pos-y": "480"},
    { "size-x": "640", "size-y": "480", "pos-x": "1920", "pos-y": "480"}
]

# アクセスするウェブサイト
sites =  [
    { "www": "http://www.amazon.co.jp"    },
    { "www": "http://www.google.com"      },
    { "www": "http://www.yahoo.com"       },
    { "www": "http://www.ibm.com"         },
    { "www": "http://www.yahoo.co.jp"     },
    { "www": "http://qiita.com/MahoTakara"}
]


# スレッドでブラウザを制御する関数
def proc(idx):
    browser = browsers[idx]
    tid = threading.get_ident()

    # ブラウザを択一
    #driver[tid] = webdriver.Chrome()
    driver[tid] = webdriver.Firefox()

    # 位置とサイズ指定
    driver[tid].set_window_size(browser['size-x'], browser['size-y'])
    driver[tid].set_window_position(browser['pos-x'], browser['pos-y'])

    # サイトを巡回
    for site in sites:
        print("idx: ", idx, "id:", threading.get_ident(), "title: ", driver[tid].title)
        driver[tid].get(site['www'])
        time.sleep(3)

    # 終了
    driver[tid].quit()        


# メイン
if __name__ == '__main__':

    # スレッドを登録
    for idx in range(0,len(browsers)):
        th_objs.append( threading.Thread( target=proc,args=(idx,)))

    # スレッドの実行開始
    for i in range(0,len(browsers)):
        th_objs[i].start()

参考資料

25
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
30