LoginSignup
8

seleniumでサイトに一度だけログインしてセッションを保存してログイン状態を保ちながら使い続ける方法

Last updated at Posted at 2023-02-03

はじめに

seleniumを使ったら自動的にサイトにアクセスして色々できて便利ですね。

seleniumの基本的な使い方については色んな記事に書いてあります。
https://qiita.com/memakura/items/20a02161fa7e18d8a693
https://qiita.com/Chanmoro/items/9a3c86bb465c1cce738a
https://qiita.com/mochio/items/dc9935ee607895420186

ただしログインする必要があるサイトを使う時に少し難易度が高くなりますね。

自動でログインする方法は意外とたくさんの記事に書いてあります。
https://qiita.com/memakura/items/dbe7f6edadd456da1c5d
https://qiita.com/studyinfra/items/144c6cb7a7444f804564
https://qiita.com/h-nabata/items/96d6a9068cb7c6ad26ae
https://qiita.com/katafuchix/items/8d4c2bed73d79ba072d9
https://qiita.com/wejhhv/items/59d739b40dc6f7f5aabc
https://qiita.com/yoshi2045/items/2fff5bf5f0fa763f7104

しかしこれらの記事はどれもログインの状態が保存されないので、毎回ログインする必要があることになります。ログイン状態を保存する方法に関しては書かれていないのです。

毎回ログインしたら手間かかりますね。それにサイトによって何度もログインしたらスパムだと思われる可能性もあります。

なので私のやりたいことは一回ログインしたらそのセッションのクッキーを保存して、この後もう一度ログインしなくても何回も使い続けられる、という方法です。

この記事はこんなことをするコードの書き方を説明します。

注意:ここで使っている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に関してはこの記事を参考に。
https://qiita.com/tanuk1647/items/4c2a305c7cc4e12ef99d

では.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()

結果としてこんなスクリーンショットが保存されますね。
wikiscreenshot.png

ログインの不具合の対策

何かの間違いでログインが失敗で終わる場合もあるので、ちゃんとログインできているか確認する必要がありますね。

方法はサイトによって違いますが、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に使うという方法もあるようです。
https://qiita.com/ytyng/items/5e6dad02a6adabc21fed
でも自分でこの方法を試しても上手くいかなかったです。それにやっぱりできれば全部seleniumでやる方が簡易です。

逆にseleniumでセッションクッキーを取得してrequestsで使うという方法もあります。
https://qiita.com/shobota/items/a4ae8f45a4620787b3e9

終わりに

以上、seleniumを使う時にセッションのクッキーを保存したり読み込んだりしてログイン状態を扱う方法について説明しました。

こうしたことで何度もログインする必要がなくて済んで便利だというわけです。

最後に言うまでもないかもしれませんが、スクレイピングはサイトに負担をかける行為だから、ほどほどにしておいた方がいいですね。これを使ってサイトに迷惑をかけてしまったらBANされるかもしれないから。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
8