1. Qiita
  2. 投稿
  3. Python

Selenium Web DriverのPythonバインディングを使ってブラウザを操作する

  • 64
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

この記事は Selenium/Appium Advent Calendar 2014 の11日目の記事です。
昨日の記事は @totutiteta さんのRobot drives on the web: Robot Framework & Selenium2Library でした。

今日はSeleniumのPythonバインディングのライブラリ selenium を使ってFirefoxを操作する方法をまとめて見ました。 またseleniumを使って操作するためのライブラリを作ってみました。

SeleniumのPythonバインディングのライブラリ selenium でFirefoxを操作してみる

この記事を書いた時点での selenium のversionは 2.44.0 が最新の用です。(おそらく2.35未満のversionでは以下のcodeは動作しないと思います)

起動

まずはブラウザを起動してみます。
今回はFirefoxを対象にしています。

profileの作成

from selenium.webdriver import FirefoxProfile

default_profile = {
    'security.warn_entering_secure': False,
    'security.warn_entering_secure.show_once': True,
    'security.warn_entering_weak': False,
    'security.warn_entering_weak._show_once': True,
    'security.warn_leaving_secure': False,
    'security.warn_leaving_secure.show_once': True,
    'security.warn_leaving_weak': False,
    'security.warn_leaving_weak._show_once': True,
    'security.warn_submit_insecure': False,
    'security.warn_viewing_mixed': False,
    'security.warn_viewing_mixed.show_once': True,
    }
profile = FirefoxProfile()
for name, value in default_profile.items():
    profile.set_preference(name, value)

Proxyの設定の作成

Proxyオブジェクトはftp_proxy, ssl_proxy, http_proxy属性で設定します。
使わない時はNoneで良さそうです。

from selenium.webdriver import Proxy
proxy = Proxy()
proxy.ftp_proxy = proxy.ssl_proxy = proxy.http_proxy = None

Firefox起動

from selenium.webdriver import Firefox
browser = Firefox(firefox_profile=profile, proxy=proxy)
browser.implicitly_wait = 10  # pageをloadするまでの待ち時間を設定
browser.delete_allcookies()  # Cookieを全消し

操作

では起動したブラウザを操作してみます。

URLを指定してページを遷移させてみる

url = 'http://qiita.com/'
browser.get(url)

id属性を指定して要素を取得

tag = browser.find_element_by_id('elemet-id')

class属性を指定して要素のリストを取得

tags = browser.find_elements_by_class_name('class-name')

CSSセレクターを指定して要素のリストを取得

以下ではinputタグのリストを取得します。

tags = browser.find_elements_by_css_selector('input')

要素をクリックする

tag.click()

Formのsubmitボタンでsubmitする

form = browser.find_elements_by_tag_name('form')[0]
for tag in form.find_elements_by_tag_name('input'):
    type_ = tag.get_attribute('type')
    if type_ == 'submit':
        entry.submit()

テキストボックスに文字を入力

textboxes = [tag for tag in browser.find_elements_by_tag_name('input') if tag.get_attribute('type') == 'text']
textbox = textboxes[0]

textbox.send_keys('CHARACTOR')

BackSpaceのキーコードを送ると文字を消せる

from selenium.webdriver.common.keys import Keys
textbox.send_keys(Keys.BACK_SPACE)  # 1文字削除
textbox.send_keys(Keys.BACK_SPACE * 10)  # 10文字削除

Windowの最大化

browser.maximize_window()

要素が表示されている状態かどうかを確認する

if tag.is_displayed():
    print(u'表示されている')
else:
    print(u'表示されていない')

javascriptを実行する

以下では画面を下方向にスクロールしています。

browser.execute_script('window.scrollTo(0, 1000)')

seleniumを使って操作するためのライブラリを作ってみた

いろいろ操作はできるんですが実際に上記を使う為にはいろいろ遷移を入れたくなることが多いと思います。現在どのページにいるから何を実行するとか、ページの状態とか、以前いたページの状態を保持しておきたいケースもあるかもしれません。(実際にそういう局面に遭遇した)

なので、ちょっとフレームワークっぽく使えるライブラリを作ってみました。

pywad

pywadはざっと説明すると起動とか制御とかを定型的に記述できるようにしたライブラリです。

インストール

Seleniumを使うのでSeleniumをインストールしておく必要があります。

$ pip install pywad

使い方

pywadにはRunnerクラスとPartクラスがあります。
Partクラスは1ページなど小さな制御単位の制御を記述する為のクラスで、Runnerクラスのパーツとなって動作します。

Partクラス

Partクラスにはis_target()メソッドとrun()メソッドがあります。
is_target()は制御対象かどうかを判定するメソッドでこのメソッドがTrueを返した場合にrun()メソッドが実行されます。実際に使うときはis_target()とrun()をオーバーライドして使う事になります。2つのメソッドともにbrowserオブジェクトとステータスを保持する為のオブジェクトを渡されるのでそれを使って処理を定義します。

from pywad.part import Part
from pywad.decorator import url_match

class GoogleTop(Part):
    def _is_search_button(self, text):
        for word in self.search_words:
            if word in text:
                return True

    @url_match('www\.google\.')
    def is_target(self, browser, status):
        return True

    def run(self, browser, status):
        entries = browser.find_elements_by_css_selector('input')
        for entry in entries:
            if entry.get_attribute('type') == 'text':
                entry.send_keys('test\n\n')

Runnerクラス

RunnerクラスはbrowserやPart間にまたがる必要のあるデータ等を管理します。
RunnerクラスにPartクラスを登録することで対象のPartを探して実行します。

from pywad.runner import Runner
def main():
    url = 'http://www.google.com'
    runner = Runner()
    runner.append(GoogleTop())
    runner.run(url)

こんな感じで記述できます。

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from pywad.runner import Runner
from pywad.part import Part
from pywad.decorator import url_match

class GoogleTop(Part):
    def _is_search_button(self, text):
        for word in self.search_words:
            if word in text:
                return True

    @url_match('www\.google\.')
    def is_target(self, browser, status):
        return True

    def run(self, browser, status):
        entries = browser.find_elements_by_css_selector('input')
        for entry in entries:
            if entry.get_attribute('type') == 'text':
                entry.send_keys('test\n\n')

def main():
    url = 'http://www.google.com'
    runner = Runner()
    runner.append(GoogleTop())
    runner.run(url)

if __name__ == '__main__':
    main()

良ければ使ってみてください

明日は?

明日は、あれ、誰だろう。誰も登録してない.oO(誰か書いてほしいな)

明日は *** です。って言えないのでアドベントカレンダーのリンクを貼っておきます。
http://qiita.com/advent-calendar/2014/selenium

ではではヾ(・д・)Byёヾ(・д・)Byё