Selenium WebDriverを使ったスプレッドシートやブラウザ操作について

## Selenium WebDriverの使い方(Mac)
以下の２パターンを紹介
①コードはRubyを使用、ブラウザはChromeを使用する場合
②コードはPythonを使用、ブラウザはChromeを使用する場合

### ①コードはRubyを使用、ブラウザはChromeを使用する場合

下記コマンドでSelenium WebDriverをインストールする

```gem install selenium-webdriver```

下記からChromeDriverをダウンロードし、解凍してrubyと同じ階層に置く
chromeの設定からバージョンを確認し、合うものを選ぶこと
https://chromedriver.chromium.org/downloads

```bash
$ which ruby
/Users/********/.rbenv/shims/ruby

#chromedriverがあるディレクトリへ移動してから
$ mv -i chromedriver /Users/*******/.rbenv/shims/.
```


コード例

```sample.rb
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

driver.navigate.to "http://google.com"
element = driver.find_element(:name, 'q')
element.send_keys "Hello WebDriver!"
element.submit
puts driver.title
driver.quit
```

コード実行
```$ ruby sample.rb```

### ②コードはPythonを使用、ブラウザはChromeを使用する場合

下記コマンドでseleniumをインストール
```pip install selenium```

pipが使えない場合は下記コマンドを実行

```bash
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python3 get-pip.py
$ which pip
```

ChromeDriverをインストールする
Chromeのバージョンを調べ、下記のサイトから合うものを選ぶと、サイト内でコマンドが表示されるのでそれをコピペ
例```pip install chromedriver-binary==93.0.4577.63.0```

※Chromeが自動更新され、バージョンが合わずコード実行できなくなった場合は、ChromeDriverを更新する必要がある
面倒な場合は以下を参照して自動更新に対応する
https://yuki.world/python-selenium-chromedriver-auto-update/

コード例

```sample.py
import time
import chromedriver_binary
from selenium import webdriver

driver = webdriver.Chrome()

driver.get('http://www.google.com/')
time.sleep(2)
search_box = driver.find_element_by_name('q')
search_box.send_keys('チョコレート')
search_box.submit()
driver.close()
```

コード実行
``` python3 sample.py```

## Pythonでスプレッドシートの操作(Seleniumなし)
### GCP管理コンソール上の準備
GCP管理コンソールに入り、Google Drive API と Google Sheets API　を有効にする
「認証情報」から「認証情報を作成」>サービスアカウント
サービスアカウント名を適当に(「Pythonから読み書きする」)
ロールは「編集者」>作成

サービスアカウントに入り、「キー」>「鍵を追加」>JSONで鍵を作成

ダウンロードした鍵は実行するPythonファイルと同じ階層に置くのがベター

### スプレッドシートの設定
サービスアカウントのメールアドレス(python@ace-~~~~~)をコピーし、
任意のスプレッドシートの「共有」の「ユーザーやグループを追加」にペースト

### ライブラリのインストール
gspread：Python3.X系でもスプレッドシートを操作できるライブラリ
oauth2client：Googleの各種APIへアクセスできるようにするライブラリ

```
$ pip install gspread
$ pip install oauth2client
```

### スプレッドシートを操作する

例題として、スプレッドシートのA1セルの値を受け取って、その値に100加算した値をB1セルに出力するプログラム
スプレッドシートのA1に「100」を入力しておく

```sample.py
import gspread
import json #不要かも

#ServiceAccountCredentials：Googleの各サービスへアクセスできるservice変数を生成します。
from oauth2client.service_account import ServiceAccountCredentials 

#2つのAPIを記述しないとリフレッシュトークンを3600秒毎に発行し続けなければならない
scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']

#認証情報設定
#ダウンロードしたjsonファイル名をクレデンシャル変数に設定（秘密鍵、Pythonファイルから読み込みしやすい位置に置く）
credentials = ServiceAccountCredentials.from_json_keyfile_name('ダウンロードしたJSONファイル名.json', scope)

#OAuth2の資格情報を使用してGoogle APIにログインします。
gc = gspread.authorize(credentials)

#共有設定したスプレッドシートキーを変数[SPREADSHEET_KEY]に格納する。スプレッドシートのURLを参照する
SPREADSHEET_KEY = 'スプレッドシートキー'

#共有設定したスプレッドシートのシート1を開く
worksheet = gc.open_by_key(SPREADSHEET_KEY).sheet1

#A1セルの値を受け取る
import_value = int(worksheet.acell('A1').value)

#A1セルの値に100加算した値をB1セルに表示させる
export_value = import_value+100
worksheet.update_cell(1,2, export_value)
```

## Pythonでスプレッドシートの値からブラウザ操作(Seleniumあり)

例として、下記のような構成の３レコードがあり、１レコードずつブラウザに入力して登録していく

| 1 | 2 | 3 | 4 | 5 |
|:-:|:-:|:-:|:-:|:-:|
|   |   |   |   |   |
|   |   |   |   |   |
|   |   |   |   |   |

```sample.py
import time
import chromedriver_binary
from selenium import webdriver
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from selenium.webdriver.support.select import Select

#スプレッドシート操作の準備
scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('ace-**************.json', scope)
gc = gspread.authorize(credentials)
SPREADSHEET_KEY = '1PrMEK**************************'
worksheet = gc.open_by_key(SPREADSHEET_KEY).sheet1

#Chrome操作の準備
driver = webdriver.Chrome()

#サインイン
driver.get("https://*******************/sign_in")
driver.find_element_by_id('email').send_keys('****@****.com')
driver.find_element_by_id('password').send_keys('********')
driver.find_element_by_xpath('//*[@id="loginform"]/div[2]/div[2]/div[2]/div/input').click()
time.sleep(1)

#iの値が5になるまでループ(３回ループ。i=2,3,4)
for i in range(2,5):
  #変数のセット
  property_name = worksheet.cell(i, 1).value #cell(2, 1)ならA2。cell(3, 1)ならA3
  property_address = worksheet.cell(i, 2).value #cell(2, 2)ならB2。cell(3, 2)ならB3
  property_building_year = worksheet.cell(i, 3).value
  property_parking = worksheet.cell(i, 4).value
  property_use_door_joiner = worksheet.cell(i, 5).value

  #登録画面へ遷移
  driver.get("https://**********************/new")
  time.sleep(1)
  driver.find_element_by_id('property_name').send_keys(property_name)
  driver.find_element_by_id('property_address').send_keys(property_address)
  Select(driver.find_element_by_id('property_building_year')).select_by_value(property_building_year) #select要素に入力
  if property_parking != None: driver.find_element_by_id('property_parking').send_keys(property_parking) #変数に値があれば実行
  if eval(property_use_door_joiner): driver.find_element_by_xpath('//*[@id="propertyBasicInfoForm"]/div[5]/div/div/div/div/label').click() #変数が文字列の'True'か'False'の場合に、bool型に変換しtrueの場合のみ実行
  driver.find_element_by_xpath('//*[@id="propertyBasicInfoForm"]/div[10]/div/button').click() #登録ボタンクリック
  time.sleep(1)

```