Python Seleniumによる自動ブラウザ操作

#Python Seleniumによる自動ブラウザ操作
　HTMLやJavascriptで提供されるサービスはユーザー目線では使いやすく便利である。SaaSなどで提供されるクラウドサービスのユーザーインターフェイスにはブラウザがよく使われ、Microsoft EdgeやGoogle Chromeがよく使われている。今回は、Chromeを自動操作することでブラウザ上で提供されるサービスを自動化する方法を紹介する。

##自動ブラウザ操作とは
　ブラウザで表示されるWeb siteは、主にHTML,CSS,Javascriptで書かれており、それぞれの画面機能はあるルールに基づいている。例えばHTMLには属性というものを各構造に指定することができ、主にid,class,div,title etcで各構造に固有の代名詞を付与することができる。自動ブラウザ操作はそのルールを指定し、命令を与えることでブラウザを操作する。

```html
属性の例
<p id="apple">りんご</p>
<p class="apple">りんご</p>
<p div="apple">りんご</p>
<p title="apple">りんご</p>
```
##Seleniumとは
　SeleniumはWebDriverを使用したAPIにより、Web ブラウザの操作を自動化するためのフレームワークであり、2004年にシカゴのThoughtWorksで始まり、JasonHuggins氏が内部のTimeand Expensesアプリケーションを自動テストするために作られた。現在ではブラウザアプリケーションの自動テスト以外でも使われている。

[Selenium Home page](https://www.selenium.dev/)

##Chrome Driver
　今回はGoogle Chromeの自動化を紹介する。Seleniumによるブラウザ操作には各ブラウザのdriverのダウンロードが必要である。以下のリンクから適当なフォルダにダウンロードして置いておこう。

[chrome driver download page](https://chromedriver.chromium.org/downloads)
[microsoft-edge driver download page](https://developer.microsoft.com/ja-jp/microsoft-edge/tools/webdriver/)

##Python selenium install
python moduleのseleniumとwebdriver-managerをpipでinstallする。

```
PS C:\Users\user> pip install selenium
Collecting selenium
  Downloading selenium-3.141.0-py2.py3-none-any.whl (904 kB)
Collecting urllib3
  Downloading urllib3-1.26.6-py2.py3-none-any.whl (138 kB)
     |████████████████████████████████| 138 kB ...
Installing collected packages: urllib3, selenium
PS C:\Users\user> pip install webdriver-manager
Collecting webdriver-manager
  Downloading webdriver_manager-3.4.2-py2.py3-none-any.whl (16 kB)
Collecting configparser
  Downloading configparser-5.0.2-py3-none-any.whl (19 kB)
Collecting crayons
  Downloading crayons-0.4.0-py2.py3-none-any.whl (4.6 kB)
Installing collected packages: crayons, configparser, webdriver-manager
Successfully installed configparser-5.0.2 crayons-0.4.0 webdriver-manager-3.4.2
```

##Sample Code
　まずは先ほどあるフォルダに置いたwebdriverを指定し、特定のweb pageを開いてみよう。
Chrome driverを自分でdownloadして特定のフォルダに置いた場合、driverへパスを通す。

```python
from selenium import webdriver
import time

driver_path = r'/path/chromedriver.exe'
driver = webdriver.Chrome(executable_path = driver_path)
driver.get('https://whc.unesco.org/')
driver.maximize_window()
```

または、webdriver_managerを使えば対応するversionのweb driverを自動でdownloadしてくれる。

```python
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
import time

driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get('https://whc.unesco.org/')
driver.maximize_window()
```
実行すると世界遺産センターのweb pageが全画面で表示される。
![sDvSDvSDvSャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/dd079827-3695-df08-8f83-4b8b10557363.png)

では次は特定の世界遺産の詳細ページへ遷移しよう。アメリカのイエローストーン国立公園のページへ行く。

```python
menu_btn = driver.find_element_by_id('menu335-link')
menu_btn.click()

list_btn = driver.find_element_by_xpath('/html/body/div[7]/span[2]/span/ul/li/span/a/strong')
list_btn.click()

time.sleep(2)
whs_btn = driver.find_element_by_xpath("/html/body/div[5]/div/div/div[1]/div/div/div/div[1]/div/div[3]/div[160]/ul/li[2]/a")
whs_btn.click()
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/f5a38a7e-c2bb-8a5e-0d47-f7b608872455.png" width="100%" height=100% >

　要素の指定にxpathを使用しているが、このxpathは自動化したいweb pageの箇所を右クリックし、検証を押してどのhtmlの記述が対応しているか確認し、検証ページの対象箇所を右クリックしてCopy->Copy full Xpathで得ることができる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/4087fde9-8056-22b6-3d14-b41e92bbdbd1.png" width="30%" height=30% >

##要素の指定方法
　要素の取得方法は以下の種類あり、web pageの仕様によって使い分ける必要がある。
###属性id
```HTML
<form id="loginForm">
  <input name="user_name" type="text" />
  <input name="password" type="password" />
</form>
```

```python
find_element_by_id('loginForm)
```
###属性xpath
ページでCtrl+Shift+I -> 対応するHTMLのソースコードで右クリック -> Copy -> Copy full XPathでパスが得られる。

```python
driver.find_element_by_xpath('/html/body/div[7]/span[2]/span/ul/li/span/a/strong')
```
###属性name
```html
      <select name="job">
         <option value="office">会社員</option>
         <option value="public">公務員</option>
         <option value="self">自営業・自由業</option>
         <option value="student">学生</option>
         <option value="house">主婦</option>
         <option value="other">その他</option>
      </select>
```
```python
find_element_by_name('job')
```
###属性class_name
```html
<span id="1-id属性-で検索" class="fragment"></span><a href="#1-id%E5%B1%9E%E6%80%A7-%E3%81%A7%E6%A4%9C%E7%B4%A2"><i class="fa fa-link"></i></a>1) id属性 で検索</h1>
```
```python
find_element_by_class_name('fragment')
```
他にも以下の種類がある。

```
find_element_by_tag_name
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_css_selector
```

##処理の種類
 指定した要素に対する処理の種類は以下のようなものがある。今回は、.click()を使いクリックをした。

```python
ページ遷移
.get("URL")
.forward()
.back()
マウント箇所の変更
.switch_to.window("windowName")
.switch_to_alert()
クリック
.click()
文字入力
.send_keys("text")
.clear()
.submit()
選択
.select_by_index(index)
.select_by_visible_text("text")
.select_by_value(value)
.deselect_by_index(index)
.deselect_by_visible_text("text")
.deselect_by_value(value)
.deselect_all()
.all_selected_options
実行
.perform()
ドラック
.actions.drag_and_drop(element_A, element_B).perform()
```
###Chromeでユーザー認証が必要な場合
会社のセキュリティでChromeをSeleniumで開く際にログインを要求される場合がある。
その際は、outlookからユーザー情報を取得することもできる。

```Python
import chromedriver_autoinstaller
import configparser
import win32com.client
 
chromedriver_autoinstaller.install()
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
accounts = outlook.Folders
user_email = str(accounts[0])
userid = user_email.split('@')[0]
print(' User email: ', user_email, '\n UserID: ', userid, sep='', end='\n')
```

##まとめ
今回はPython seleniumによるブラウザ自動操作の方法を紹介した。個人的にはxpathはコピーするだけで要素のパスが取得できるので、xpathが便利かなと思う。

##参考文献
[Selenium 逆引き](https://www.seleniumqref.com/api/webdriver_gyaku.html)