この記事は 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はざっと説明すると起動とか制御とかを定型的に記述できるようにしたライブラリです。
インストール
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ё