1. はじめに
京大の授業資料はPandAかKULASISにアップロードされることが多いが、複数ファイルを一括でダウンロードできない!
毎回1つずつファイルを開いて保存するのはあまりにも面倒なため、
- PandA にログインし、
- 指定した科目のレジュメがあるページのURLを取得し、
- レジュメを一括ダウンロードする
以上のプログラムを書いてみたところ結構苦労したので、その時学んだことをまとめました。プログラム書くほうが手動でダウンロードするより時間かかってる、とか言わない(8時間はかかった)。
2. 環境
Python3.6.6
用いたライブラリは以下の通り。
beautifulsoup4 4.7.1
selenium 3.141.0chromedriver 2.45
2. そもそもPandAをクローリングしていいのか?
機械的ダウンロードが禁止されているサイトは少なくありません。PandAにはrobots.txtのようなファイルは、確認した範囲では存在しなかったので、プログラムでレジュメをダウンロードすることはおそらく想定されていない(当然といえば当然)。しかし、規程・関連規則にも機械的ダウンロードについての記載はない。5秒間隔開けるので許してください。
だが、BeautifulSoupでの解析を詳細に書くと、京大生しか見れないサイトの構造が世界に公開されてしまうので、全コードは公開できません。ログインの部分は他のサイトでもそのまま使えると思います。
3. seleniumでログインする
requestsでやろうとしたが、クローリング初心者にはPandAの壁は高すぎた。この記事を参考に、初心者にも扱いやすいseleniumを用いました。
import os
import platform
import sys
import re
import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
次に、この記事に従って、
ファイルをダウンロードしやすいように、seleniumでドライバーを開くときのoptionを設定します。
# driverを設定
options = webdriver.ChromeOptions()
options.add_experimental_option('prefs', {
'download.default_directory': download_dir,
'plugins.always_open_pdf_externally': True})
options.add_argument('--head')
次に、自分のIDとパスワードを入れ、ログイン。
# login info
username = '' # ここに自分のIDを入力
password = ''
options.add_argument('--head')
# Chromeを起動
driver = webdriver.Chrome(executable_path='./chromedriver', chrome_options=options)
# ログインページを開く
url = 'https://panda.ecs.kyoto-u.ac.jp/portal/login'
driver.get(url)
# ログイン情報を入力してログイン
driver.find_element_by_id('username').send_keys(username)
driver.find_element_by_id('password').send_keys(password)
driver.find_element_by_name('submit').send_keys(Keys.ENTER)
# ログイン後のトップページのhtmlを取得
soup = BeautifulSoup(driver.page_source, "html.parser")
ここからBeautifulSoupオブジェクトを解析し、目的の科目のページへ飛びます。
Google chrome の検証モードを利用しながら、BeautifulSoupオブジェクトから'.*.pdf'を探そうとしても......。
となり困り果てました。調べたところ、Javascriptが動いている環境だと、レスポンスと検証モードで表示されるElementとが異なることがよくあるそうです。今時Javascriptが動いてないページの方が珍しい気がするが、どうすればいいんでしょう。教えて有識者。
なので、そこをselenium を用いて修正。目的のページへ飛べました。
(selenium、動作が重たかったので次回以降はrequestsでできるようになりたい)
参考にした記事まとめ
https://shimi-dai.com/python-selenium-web-scraping-at-login-page/
https://qiita.com/memakura/items/f80d2e2c59514cfc14c9
https://teratail.com/questions/32756