背景 (Situation & Task)
子供を保育園にあずけていると写真を保育園のスタッフが撮影をしてくれていることがある。
こういった写真について、共有される方法はいくつかあり、その中の一つの方法として、「egaoスクールフォトサービス」というものがある。スタジオアリスのサービスなのだが、我が子の写真を選んで購入し、後日ウェブからダウンロードできるなかなか優れたシステムだと思う。
しかしながら、たいていの親は、あれよあれよとたくさん写真を選ぶ訳だが(我が家は百枚を超えた)、なんとこのウェブサービス、一括ダウンロードのオプションがない。一つずつクリックしてるとだんだんどれがなんだかわからなくなってくる。。。。恐ろしい。。。。
きっとまた同じようなシチュエーションになることが想定されるので、自分の備忘録を兼ねて作成をしておく。
なお、本記事は2020年3月時点のegaoのウェブサイトを前提に作成しており、egaのウェブサイトの仕様変更などがあった場合には、使い物にならない可能性もある。
(できれば、ウェブサイト仕様変更があれば一括ダウンロードをつけてほしい)
実施しようとしたこと(Action)
とりあえず下記の流れでダウンロードをすることを想定した。
1.サイトにアクセス
2.ログインをする
3.ダウンロード用のページに遷移
4.表示されている画像(購入した写真)を一括でダウンロードする
事前に準備すること
実際に進めるための事前準備は下記になる。
・Selenium, BeautifulSoupをインストールしておくこと。
(特にPC側におく、webdriverのversionなどは気をつけるように)
・ログインするID(Email address)/Password
・ダウンロードしたい写真のある一覧ページのURLをコピペしておく。
事前設定については参照した記事(本記事最後)が詳しいのでここでは割愛する。
実際に行った手順(Result)
まずは必要なライブラリをインストールした。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
次に自動で操作するためのChrome.Webdriverを立ち上げをした。
driver = webdriver.Chrome()
driver.implicitly_wait(3)
立ち上げた後、下記コマンドで、該当のウェブサイトにアクセスをしてログインをする。ちなみに自動で表示されるウェブ画面を小さくするとxmlの構造が変わるようでerrorになる可能性もある。ここではその辺りは深く対応を考えてないので、注意が必要。
url = "https://egao.photo/store/" # ログインページのあるウェブページ
user = "hoge@gmail.com" # 自分のE-mailを記載
password = "hogehoge" # 設定してあるPasswordを記載
driver.get(url)
elem = driver.find_element_by_id("btn-login")#トップページのログインボタンをおす
elem.click()
elem = driver.find_element_by_id("inputEmail")#メールアドレス入力
elem.clear()
elem.send_keys(user)
elem = driver.find_element_by_id("inputPassword")#Password入力
elem.clear()
elem.send_keys(password)
elem = driver.find_element_by_xpath("//*[@id='login-modal']/div/div/div[2]/form/div/div[3]/div[1]/button")#ログインのボタンをおす
elem.click()
elemの手順について画像で手順を記載すると下記のような形になる。最後のログインではidが降ってあればよかったが見つからなかったのでXpathを用いて指定している。
次に自分が一括ダウンロードをしたいと考えているウェブページを指定して、webdriverを使ってページ遷移するようにする。
url_target = "https://egao.photo/store/EventPhoto/Download?Model=hogehogehogehogehoge-1"
driver.get(url_target)
ここまでが一旦Selenium baseで行う主なワークとなり、次にBeautiful Soupの出番になる(なおWebDriverで表示されたブラウザは削除しないこと)。Beautiful Soupで現在のwebdriverが開いているページを読み込み、その構文解析を行った。
page_source = driver.page_source
soup = BeautifulSoup(page_source, 'lxml')
ダウンロード対象の画像には個別のnameとしてphotoIdが共通して入ってました。まず、そのphotoIdを含む部分を抽出し、listに格納。その後、さらにid(各画像ごとの個別のid)を抜き出した。
linklist = []
linklist = soup.find_all('button', attrs={'name': 'photoId'})
linklist_2 = []
for a in linklist:
b = a.attrs['id']
linklist_2.append(b)
linklist_2の中身で下記のようなものが取れていればOK。
['Download_XYXYXYXYXYYYY',
'Download_YYYYYYYYYYYYY',
'Download_XXXXXXXXXXXYY',
'Download_XXXXXXXXXXXXY']
最後にSeleniumに戻って、各idの画像をダウンロードを実行した。
for a in linklist_2:
elem = driver.find_element_by_id(a)
elem.click()
ここまでの方法だと一回で一括ダウンロードできるのはウェブページに表示されるMAX分までなので、別のページについては同じようにpage遷移をし、改めて同様のコマンドを実施することで回収ができた。
感想&今後対応をしたいこと
次回たくさんダウンロードが必要になった際には冗長になってしまってる部分含めもう少し自動化しようと考えています。とにかく、これでまた同じように大量の画像のダウンロードが必要になった際には、楽ができることになりましたのでよかったなと思います。
参考にしたウェブページ
ほとんど必要なことは下記の2つに書いてありました。感謝。
・【Selenium】ログインしてデータをcsvに書き出す【BeautifulSoup】
・Pythonのスクレイピングで、いらすとやの画像を一気にダウンロード