gologiusの巣

プログラミング、モデリングなどのメモです。誰かの役に立てるとうれしいです。

【Python】【Selenium】 Webサイトから自動でファイルDLする

概要

  • Webサイトにアクセス→ログイン→ボタンを押してファイルをDL

みたいな処理を自動化したい。

会社で使おうと思ったスクリプトなので、具体的なサイトは出せないのは勘弁してください。 あと特定サイトを例に挙げると、そのサイトの負荷を上げそうなのでそれも理由にあります。

環境構築

PythonSeleniumを使用します。 Pythonは環境構築が楽で、パッケージがいろいろあるのでいいですよね。

OSはWin10です。 ブラウザはクロームを使用します。

Pythonの環境

初めて環境構築する場合は、 以下のリンクからインストーラをDLして実行すると、 Python、エディタ(Spyder)など全部入ります。

初めて入れるならPython 3.X版にしましょう。 2.X版は2020年にサポートが終了します。

ちなみに私はPython2のAnacondaが入っている状態でさらにPython3版をインストールしたため、 パスがめちゃくちゃになりました。

解決方法としては、環境変数を適当に消してから再インストールすると正常に動作するようになりました。

Seleniumのインストール

コマンドプロンプト

pip install selenium

以上。

次、ここからwebdriverをDLして、適当なディレクトリに置いておきます。

パスは後で使用するので覚えておきましょう。

ちなみに、これをDLしてない or スクリプト上でパス指定が間違っている場合、以下のエラーが出ます。

WebDriverException: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

実装

最初に書きましたが会社で使用しようとしてたので、xpathはごまかしてます。 かといって適当なサイトを例に挙げて、そのサイトの負荷上げるのも犯罪臭がするので・・・

gist.github.com

想定するシナリオは

  • Webページにアクセス
  • ダウンロードする資料の番号を入力
  • ボタンを押す
  • 別ウインドウでポップアップが出る
  • DLボタンを押す

となります。

driver.implicitly_wait(WAIT_SEC) はかなり重要です。 要素がなくても'WAIT_SEC'秒だけ待ち続けます。 これを指定することで、読み込みが完了しておらず、要素がないのでエラーになる、といった事態を避けられます。

また、driver.find_element_by_xpath()xpathを指定して要素を取得できます。 xpathの説明はこの記事が詳しいです。 上の例だと、

  • //input[@id='page'] → ページ全体(//)の中で<input id="page"></input>を取得
  • //a[@onclick='download(); → ページ全体(//)の中で<a onclick="download"></a>を取得

となります。 要素取得後はsend_keys()で値セット、click()で要素をクリックしています。 ちなみにsend_keys()は複数同時入力(Ctrl+Cなど)に対応しているので、複数形(keys)になってるみたいです。今回は使ってませんが。

ファイルのダウンロードの終了検知は、Seleniumの機能ではできなさそうでね。 ダウンロードが完了したらファイルが作成されるはずなので、ファイル名の検出などで対応する必要がありそうです。

結論

個人的にはdriver.implicitly_wait()が便利。 いちいち読み込み完了を検知するスクリプトを書かなくともよいのは便利。

あと、こんな環境が一瞬でインストールできるPythonが便利ですね。 ただ僕は型が明示的に決まる言語の方が好きです。C#とか。

  • ゲーム、アプリを作る→C#
  • 若干めんどい数学計算、機械学習、サーバー弄り系→Python

みたいな使い分けになってきてますね。

そろそろWeb系も勉強したいところ。