はじめに
- Python の Selenium を使って、ログインありの web サイトのページを pdf としてダウンロードした時のメモです
- Selenium は自動でブラウザを操作できるツールです。web ページの自動テストなどに使う事が多いようです
環境
- macOS Mojave 10.14.6
- python 3.6.0
- Chrome
事前準備
以下ライブラリを pip でインストールします
- selenium
- chromedriver-binary
pip install selenium chromedriver-binary
selenium での操作
ドライバの設定
- selenium でブラウザを操作するために必要なドライバをインスタンス化します
import chromedriver_binary
from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
ログインする
- セキュリティのため、ログインに必要な id とパスワードを環境変数から読み取るようにします
import os
login_id = os.environ["MY_LOGIN_ID"]
login_password = os.environ["MY_LOGIN_PASSWORD"]
-
driver.get()
で URL を指定し、ログインページを取得します - 今回はログイン対象ページの ID/パスワードを入力するテキストボックスとログインボタンが id 属性値で特定できたため、
driver.find_element_by_id()
でページの要素を取得します - 取得した要素に対して
send_keys()
で値を入力し、submit()
でログインします
driver.get("<ログインページのURL>")
driver.find_element_by_id("username").send_keys(login_id)
driver.find_element_by_id("password").send_keys(login_password)
driver.find_element_by_id("authform").submit()
クリックする
- 取得した要素に対して
click()
でクリックします
driver.find_element_by_id("hogeid").click()
表の中の要素を取得する
- 表の中の要素の取得には
find_elements_by_xpath()
を使いました - XPath の取得には chrome のデベロッパーツールが便利です。対象要素の HTML を右クリックして Copy XPath でコピーできます
- 以下のような表の
dataA-2
のリンクを取得したいとします
header1 | header2 | header3 |
---|---|---|
dataA-1 | dataA-2 | dataA-3 |
dataB-1 | dataB-2 | dataB-3 |
html
<table class="hoge fuga piyo">
<thead>
<tr>
<th>header1</th>
<th>header2</th>
<th>header3</th>
</tr>
</thead>
<tbody>
<tr>
<td>
dataA-1
</td>
<td>
<a href="http://dummy">dataA-2</a>
</td>
<td>
dataA-3
</td>
</tr>
<tr>
<td>
dataB-1
</td>
<td>
<a href="http://dummy">dataB-2</a>
</td>
<td>
dataB-3
</td>
</tr>
</tbody>
</table>
python
driver.find_element_by_xpath(
"//table[contains(@class,'hoge')]/tbody/tr[1]/td[2]/a")
- 今回は取得したい表の class が複数指定されていたので
contains
でフィルタしました - class が一つの場合は
"//table[@class='hoge']/tbody/..."
でよさそう
指定した秒数待つ
- ページに遷移してから表の表示に少し時間がかかっていたようで、要素の取得ができなかったことがありましたが、
implicitly_wait()
で待ち時間を設定するとうまくいきました
driver.implicitly_wait(n)
ページを pdf としてダウンロードする
- chrome の印刷機能で pdf として保存します
- ドライバにオプションを追加し、ダウンロードするパスを指定します
- ドライバのオプションに
--kiosk-printing
を加えると、印刷ダイアログを開いた後に自動で印刷ボタンを押してくれます- ドライバのオプションに
--headless
オプションを加えると、ブラウザを立ち上げずに実行する「ヘッドレスモード」で実行できますが、--kiosk-printing
オプションとの併用はできないようです。実際に併用してみましたが pdf をダウンロードできませんでした(悲)
- ドライバのオプションに
ドライバの設定
options = webdriver.ChromeOptions()
options.add_experimental_option("prefs", {
"download.default_directory": "~/Downloads"
})
options.add_argument('--kiosk-printing')
driver = webdriver.Chrome(options=options)
- 印刷ダイアログを開くためには、javascript を実行する
execute_script()
を使用しました。ドライバの--kiosk-printing
オプションにより、これでPDFが保存されます
driver.execute_script('window.print();')