はじめに
パスワード管理って大変ですよね。今までTrendMicroのPassword Managerを使用してきたんですが、
Chromeの拡張機能がたまに使い物にならない時があって、なんかいいのないかなと思っていたところ
Bitwardenが無料でいい感じだったので乗り換えを決めました。
Password ManagerでパスワードファイルをCSV出力して、
Bitwardenでインポートしたら乗り換えは一瞬かと思ったんですが、
インポートのオプションでPassword Managerが選択肢になかったためSeleniumで自動化させてみました。
環境
MacOS: Catalina 10.15.7 Python: 3.8.3 Selenium:: 3.141.0 Google Chrome: 87.0.4280.88 chromedriver: 87.0.4280.88Bitwardenへの会員登録
まずはBitwardenに会員登録しましょう。 UIが今っぽくて良いですね。
Seleniumの環境構築
こちらの方の記事を参考にして設定しました。Python + Selenium で Chrome の自動操作を一通り
https://qiita.com/memakura/items/20a02161fa7e18d8a693
以下のコマンドでSeleniumをインストールします。
pip install selenium
chromedriverをpip installで入れてみたのですが、
私の場合Chromeとのバージョンが不一致でエラーが出たため、
以下のサイトからマッチするバージョンのchromedriverを落としてきました。
ダウンロード後はお好きな場所において下さい。
私はライブラリ配下に以下のようにフォルダを作成して格納しました。
/Library/ChromeDriver/chromedriver
これでSeleniumのセットアップは完了です。
必要なライブラリのインポート
今回使用するライブラリたちをインポートしていきます。from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
import datetime
import csv
import codecs
chromedriverでBitwardenにアクセス
私のようにchromedriverをサイトからダウンロードした人は 下記のようにpathを指定してあげる必要があります。driver = webdriver.Chrome(executable_path='/Library/ChromeDriver/chromedriver')
# アクセスするウェブサイトのURLを指定
driver.get('https://vault.bitwarden.com/#/')
# ログイン画面に遷移したら2秒待機
time.sleep(2)
# ブラウザを閉じる
driver.quit()
chrome driverをpip installした人は
import chromedriver_binary
を追加してあげて下さい。
これでBitwardenにアクセスするプログラムができました。
ログインの実装
ログイン画面まで行けたので、ログインIDとパスワードを入力して、ログインボタンをクリックするところまでやってみます。driver = webdriver.Chrome(executable_path='/Library/ChromeDriver/chromedriver')
# アクセスするウェブサイトのURLを指定
driver.get('https://vault.bitwarden.com/#/')
# ログイン画面に遷移したら2秒待機
time.sleep(2)
# ログインIDを入力
login_id = driver.find_element_by_name("Email")
login_id.send_keys("自分のメールアドレス")
# パスワードを入力
master_password = driver.find_element_by_name("MasterPassword")
master_password.send_keys("自分のパスワード")
# ログインボタンクリック
login_btn = driver.find_element_by_xpath("/html/body/app-root/app-frontend-layout/app-login/form/div/div/div/div/div[4]/button")
login_btn.click()
time.sleep(5)
# ブラウザを閉じる
driver.quit()
ログインID/パスワードのフォームは
find_element_by_name
で探すことができます。
ログインボタンはnameの指定がなかったため、XPATHで指定してます。
ブラウザのF12ボタンを押して、開発者ツールで該当箇所のnameだったり、idだったりを探して
それに対応する"find_element_by~"で指定する感じです。
これでログインまではできました。
CSVファイルから登録したいサイトのURL/ID/PWを読み込んで登録していく
登録したいサイトが200件近くあったので、手作業は無理と判断。 CSVファイルから読み込んで登録していきます。ちなみに、今回のCSVファイルは以下のようなフォーマットになっています。
サイト名,サイトURL,ユーザー名,パスワード
driver = webdriver.Chrome(executable_path='/Library/ChromeDriver/chromedriver')
# アクセスするウェブサイトのURLを指定
driver.get('https://vault.bitwarden.com/#/')
# ログイン画面に遷移したら2秒待機
time.sleep(2)
# ログインIDを入力
login_id = driver.find_element_by_name("Email")
login_id.send_keys("自分のメールアドレス")
# パスワードを入力
master_password = driver.find_element_by_name("MasterPassword")
master_password.send_keys("自分のパスワード")
# ログインボタンクリック
login_btn = driver.find_element_by_xpath("/html/body/app-root/app-frontend-layout/app-login/form/div/div/div/div/div[4]/button")
login_btn.click()
time.sleep(5)
# CSVファイルの読み込み
# サイト名で日本語を扱うので、文字コードはShit-JISを選択
with codecs.open('CSVファイルのPATH',"rb", "Shift-JIS", "ignore") as f:
for row in reader:
# CSVファイルの1行目にヘッダーがある場合は、以下で読み込みをスキップさせる
next(reader)
#ログインID/PWと同じ要領で各フォームの要素を取得し、クリック/入力をしていく
# アイテム追加
add_item = driver.find_element_by_xpath("/html/body/app-root/app-user-layout/app-vault/div/div/div[2]/div/div/button")
add_item.click()
# 名前の入力
enter_name = driver.find_element_by_name("Name")
enter_name.send_keys(row[0])
print("名前を入力しました")
# ユーザー名の入力
enter_username = driver.find_elements_by_id("loginUsername")
enter_username[0].send_keys(row[2])
print("ユーザー名を入力しました")
# パスワードの入力
enter_password = driver.find_elements_by_id("loginPassword")
enter_password[0].send_keys(row[3])
print("パスワードを入力しました")
# URLの入力
enter_url = driver.find_elements_by_xpath("/html/body/app-root/app-user-layout/app-vault/app-modal/app-vault-add-edit/div/div/form/div[2]/div[5]/div[1]/div/input")
enter_url[0].send_keys(row[1])
print("URLを入力しました")
# 保存ボタンクリック
click_save = driver.find_elements_by_xpath("/html/body/app-root/app-user-layout/app-vault/app-modal/app-vault-add-edit/div/div/form/div[3]/button[1]/span")
click_save[0].click()
# 次の入力まで2秒待機
time.sleep(2)
# ブラウザを閉じる
driver.quit()
nameやidで拾ってこれないモノは、XPATHで指定しています。
enter_username[0].send_keys(row[2])
などのように、[0]がついているモノは変数の型がlistのため必要とのこと。
これを付けずに実行したら
AttributeError: 'list' object has no attribute 'send_keys',
というエラーが出ました。
こちらを参考にして、取りえあず真似してみたらできた。
理由はよくわからないけど、動いたからひとまず放置。。。
以上です。
参考
>Python + Selenium で Chrome の自動操作を一通り >https://qiita.com/memakura/items/20a02161fa7e18d8a693AttributeError: 'list' object has no attribute 'send_keys', python+selenium Enables automatic login of QQ space pages.
https://programmersought.com/article/33681438536/