概要
クラウドサービスやWEBシステムを利用している場合に、入力フォームに複数のデータをまとめて入力したいようなケースはあるかと思います。(きっとあるはず・・・)
今回は、Excelに記載されている複数のデータをGoogleのFormsで作成した入力フォームに連続して登録するプログラムを作成したいと思います。
準備
①Excel(example.xlsx)
下記のようなExcelを用意しました。データは2件です。
名前 | 参加 | 知ったきっかけ | コメント |
---|---|---|---|
鈴木 一郎 | はい | 友人 | 宜しくお願いします |
田中 次郎 | いいえ | 広告 | 今回は欠席させていただきます |
②入力するWebForm
ブラウザから入力するWebFormとして、下記のようなフォームをGoogle Formsで作成しました。
https://forms.gle/VfMxiSAxrQjEpyv99
入力項目は、下記の4項目となります。
- 名前:テキストエリア
- 参加:ラジオボタン
- 知ったきっかけ:プルダウン
値:ウェブサイト、友人、ニュースレター、広告 - コメント:テキストエリア
プログラム
モジュールのインストール
今回は、Excelとブラウザを操作する為に下記のモジュールが必要になります。
- Excelの操作 openpyxl
- ブラウザの操作 selenium
まだインストールされていない時は、インストールしてください。
# Excel操作用のモジュールのインストール
pip install openpyxl
# ブラウザ操作用のモジュールのインストール
pip install selenium
インポート
#! python3
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from time import sleep
import openpyxl
Excelからデータを読み込み
# EXCELを開く
wb = openpyxl.load_workbook('example.xlsx')
sheet = wb.get_sheet_by_name('Sheet1')
# EXCELからデータを取得
rows = 0
add_items = []
while True:
if not sheet.cell(2 + rows, 1).value:
break
item = {}
item['name'] = sheet.cell(2 + rows, 1).value.strip()
item['join'] = 1 if sheet.cell(2 + rows, 2).value.strip() == 'はい' else 2
item['started'] = sheet.cell(2 + rows, 3).value.strip()
item['comment'] = sheet.cell(2 + rows, 4).value.strip()
add_items.append(item)
rows += 1
ブラウザの設定およびフォーム入力処理
本来であれば、HTMLの要素を見つける方法は、
- cssのクラス名:find_element_by_class_name(xxx)
- id属性:find_element_by_id(xxx)
- name属性:find_element_by_name(xxx)
等を用いるのが簡単なのですが、google Formsで作成した場合は上記の判定が使えなかったので、XPATHでHTMLのノードを検索する方法をとっております。
# ブラウザ設定
options = Options()
options.add_experimental_option('detach', True) # スクリプトが終了してもブラウザを閉じない設定
browser = webdriver.Chrome(options=options)
browser.set_page_load_timeout(3) # ページがロードされるまでの待ち時間
browser.implicitly_wait(3) # 指定したドライバの要素が見つかるまでの待ち時間
# WEBフォームに入力処理
for item in add_items:
browser.get("https://forms.gle/VfMxiSAxrQjEpyv99")
sleep(1) # 結局はこれがないと動かない・・・
try:
# テキストエリア(名前)
elem = browser.find_element(By.XPATH,"(//form[1]//textarea)[1]")
elem.send_keys(item['name'])
# ラジオボタン(参加)
browser.find_element(By.XPATH,f"(//form[1]//div[@class='vd3tt'])[{item['join']}]").click()
# プルダウン(きっかけ)
browser.find_element(By.XPATH,"//form[1]//div[@class='ry3kXd']").click()
sleep(0.5)
browser.find_element(By.XPATH,f"(//form[1]//div[@data-value='{item['started']}'])[2]").click()
sleep(0.5) # これがないと上記が未選択になる
# テキストエリア(コメント)
elem = browser.find_element(By.XPATH,"(//form[1]//textarea)[2]")
elem.send_keys(item['comment'])
# 送信ボタン
browser.find_element(By.XPATH,"//form[1]//span[contains(text(), '送信')]").click()
sleep(3)
except:
print('error:要素が見つかりませんでした')
browser.quit() # ブラウザ終了
ところどころに存在するsleepは、処理に時間が掛かる等で少し時間をあけないとうまく動かない為、時間を調整する為に入れております。
テスト
pythonスクリプトを実行してみます。
下記の動画のように、正しくデータが登録される事が確認できました。
その他
XPathが正しいか検証する方法
XPathの記述があっているかプログラムを毎回実行する事はすごく面倒です。
Chromeのデベロッパーツールのコンソールで、下記のようにするとXPathが正しければ要素を取得する事ができます。(間違っている場合は空の要素が返ります。)
# XPathで要素を取得
$x('(//form[1]//textarea)[1]')