はじめに
seleniumを使ったら自動的にサイトにアクセスして色々できて本当に便利ですよね。
seleniumの基本的な使い方については色んな記事に書いてあります。
ただしログインする必要があるサイトを使う時に少し難易度が高くなりますね。
自動でログインする方法は意外とたくさんの記事に書いてあります。
- Python + Selenium + Chrome で自動ログインいくつか
- 【Googleログイン自動化】Python×seleniumでGoogleにログインする
- SeleniumでSlackに自動でログインする
- selenium から Twitter にログインして投稿
- PythonとSeleniumで自動ログインを行う
- 楽天銀行サイトにPythonとSeleniumを使ってログインする
しかしこれらの記事はどれもログインの状態が保存されないので、毎回ログインする必要があることになります。ログイン状態を保存する方法に関しては書かれていないのです。
毎回ログインしたら手間かかりますね。それにサイトによって何度もログインしたらスパムだと思われる可能性もあります。
なので私のやりたいことは一回ログインしたらそのセッションのクッキーを保存して、この後もう一度ログインしなくても何回も使い続けられる、という方法です。
この記事はこんなことをするコードの書き方を説明します。
注意:ここで使っているseleniumのバージョンは4.8.0です。3.xを使っている場合なら書き方は色々違います。
基本操作
ここて例としてwikipediaを使います。まずはseleniumでwikipediaのログインのページにアクセスしてログインする方法から始めます。
from selenium import webdriver
from selenium.webdriver.common.by import By
login_url = 'https://ja.wikipedia.org/w/index.php?title=特別:ログイン'
username = 'ahoge' # ユーザーの名前(ここではただ適当に書いています)
password = 'afuga' # パスワード
driver = webdriver.Chrome()
driver.get(login_url) # ログインのページにアクセス
driver.set_window_size(600,600)
# ユーザー名入力
name_box = driver.find_element(By.NAME,'wpName')
name_box.send_keys(username)
# パスワード入力
password_box = driver.find_element(By.NAME,'wpPassword')
password_box.send_keys(password)
# ログイン状態を保つためのチェックボックス
remember_box = driver.find_element(By.NAME,'wpRemember')
remember_box.click()
そして最後に
name_box.submit()
を追加したらログインすることになります。
これでwikipediaにログインして色々やることができますね。
ログインしてセッションクッキーを保存する
次はログインした後セッションのクッキーを保存する方法についてです。
保存する方法は色々ありますが、ここではpickleで保存します。jsonを使うのも悪くない方法です。
pickleに関してはこの記事を参考に。
では.get_cookies()
メソッドを使ってクッキーを取得してpickleで保存するコードは以下です。
from selenium import webdriver
from selenium.webdriver.common.by import By
import pickle
login_url = 'https://ja.wikipedia.org/w/index.php?title=特別:ログイン'
username = 'ahoge' # ユーザーの名前
password = 'afuga' # パスワード
cookies_file = 'morokoshi.pkl' # クッキーを保存するファイルの名前
driver = webdriver.Chrome()
driver.get(login_url)
name_box = driver.find_element(By.NAME,'wpName')
name_box.send_keys(username)
password_box = driver.find_element(By.NAME,'wpPassword')
password_box.send_keys(password)
remember_box = driver.find_element(By.NAME,'wpRemember')
remember_box.click()
name_box.submit()
cookies = driver.get_cookies() # クッキーを取得する
pickle.dump(cookies,open(cookies_file,'wb')) # クッキーを保存する
driver.quit() # ウィンドウを閉じる
これでセッションのクッキーはmorokoshi.pkl
に保存して、後で使えるようになります。
セッションクッキーを読み込んで使う
次は保存されたクッキーをpickleファイルから読み込んで使うコードです。
from selenium import webdriver
import pickle
web_url = 'https://ja.wikipedia.org/wiki/日本書紀' # 入りたいページ
cookies_file = 'morokoshi.pkl' # クッキーを保存するファイルの名前
driver2 = webdriver.Chrome()
cookies = pickle.load(open(cookies_file,'rb')) # クッキーを読み込む
driver2.get(web_url) # まずは一度サイトにアクセス
for c in cookies: # クッキーを設定する
driver2.add_cookie(c)
driver2.get(web_url) # クッキーを設定した後またアクセス
driver2.set_window_size(800,600)
成功したら結果はこんな感じでしょう。ちゃんとユーザー名が上に書いてあります。
クッキーを設定する時は.add_cookie()
メソッドを使って一つずつ追加することになります。
ただしここで注意する必要があるのは、.add_cookie()
を使う前にまずは一度同じサイトにアクセスする必要があります。そうしなければこのようなエラーが出ます。
InvalidCookieDomainException: invalid cookie domain
(Session info: chrome=109.0.5414.120)
先にアクセスするurlは入りたいページと同じurlである必要ないのですが、同じサイトである必要があります。
例えば今回はまずhttps://ja.wikipedia.org
にアクセスするのも問題ないです。でもhttps://fr.wikipedia.org
は駄目みたい。
一度だけログインしたらセッションを使い続ける
実際に使う時にこのように書くと便利です。
from selenium import webdriver
from selenium.webdriver.common.by import By
import pickle,os
login_url = 'https://ja.wikipedia.org/w/index.php?title=特別:ログイン' # ログインのページ
web_url = 'https://ja.wikipedia.org/wiki/Qiita' # 入りたいページ
username = 'ahoge' # ユーザーの名前
password = 'afuga' # パスワード
cookies_file = 'morokoshi.pkl' # クッキーを保存するファイルの名前
driver = webdriver.Chrome()
# まだクッキーを持っていない場合新しくログインして保存する
if(not os.path.exists(cookies_file)):
driver.get(login_url)
name_box = driver.find_element(By.NAME,'wpName')
name_box.send_keys(username)
password_box = driver.find_element(By.NAME,'wpPassword')
password_box.send_keys(password)
remember_box = driver.find_element(By.NAME,'wpRemember')
remember_box.click()
name_box.submit()
cookies = driver.get_cookies()
pickle.dump(cookies,open(cookies_file,'wb'))
# すでにクッキーを持っている場合読み込んで使う
else:
cookies = pickle.load(open(cookies_file,'rb'))
driver.get(web_url)
for c in cookies:
driver.add_cookie(c)
# やりたいことなど
driver.get(web_url)
driver.set_window_size(800,700)
driver.save_screenshot('wikiscreenshot.png')
driver.quit()
ログインの不具合の対策
何かの間違いでログインが失敗で終わる場合もあるので、ちゃんとログインできているか確認する必要がありますね。
方法はサイトによって違いますが、wikipediaでは例えばログイン成功したらそのページの中に自分のユーザー名がついているはずだから、今回はページのコードを取得してその中にユーザー名が含まれるかどうかという情報を利用します。
書いてみたらこんな感じでしょう。
from selenium import webdriver
from selenium.webdriver.common.by import By
import pickle,os
login_url = 'https://ja.wikipedia.org/w/index.php?title=特別:ログイン'
web_url = 'https://ja.wikipedia.org/wiki/Qiita'
username = 'ahoge'
password = 'afuga'
cookies_file = 'morokoshi.pkl'
def login():
driver.get(login_url)
name_box = driver.find_element(By.NAME,'wpName')
name_box.send_keys(username)
password_box = driver.find_element(By.NAME,'wpPassword')
password_box.send_keys(password)
remember_box = driver.find_element(By.NAME,'wpRemember')
remember_box.click()
name_box.submit()
cookies = driver.get_cookies()
pickle.dump(cookies,open(cookies_file,'wb'))
def load_cookies():
cookies = pickle.load(open(cookies_file,'rb'))
driver.get(web_url)
for c in cookies:
driver.add_cookie(c)
driver = webdriver.Chrome()
if(not os.path.exists(cookies_file)):
login() # ログインしてクッキーを保存する
else:
load_cookies() # クッキーを読み込む
driver.get(web_url)
# クッキーを設定してもログイン状態になっていない場合は一応もう一度ログインを試す
if('<span>%s</span>'%username not in driver.page_source):
login()
if('<span>%s</span>'%username in driver.page_source): # 無事でログインできた場合、やりたいコードを実行する
'''
やりたいことなど
'''
else: # 失敗する場合
print('何か不具合があるみたい')
関係ある方法
requestsで取得したログインセッションクッキーを使ってseleniumに使うという方法もあるようです。
でも自分でこの方法を試しても上手くいかなかったです。それにやっぱりできれば全部seleniumでやる方が簡易です。
逆にseleniumでセッションクッキーを取得してrequestsで使うという方法もあります。
終わりに
以上、seleniumを使う時にセッションのクッキーを保存したり読み込んだりしてログイン状態を扱う方法について説明しました。
こうしたことで何度もログインする必要がなくて済んで便利だというわけです。
最後に言うまでもないかもしれませんが、スクレイピングはサイトに負担をかける行為だから、ほどほどにしておいた方がいいですね。これを使ってサイトに迷惑をかけてしまったらBANされるかもしれないから。