【Pythonスクレイピング】Javascriptによる動的ページでリンクURLが属性「href=”#”」のボタンをクリックして描写されたページのソースを取得する方法

Pythonのスクレイピングで困るページの事例の1つ

Pythonのスクレイピングで、その初歩的・基本的なやり方だけでは上手くいかない事例はいろいろありますが、私が困った事例に以下の4つの条件をすべて満たすページがありました。

  • HTMLでiframe(インラインフレーム)が使われている
  • Javascriptが使われている
  • ページ遷移のボタンには、<a href=”#”>が設定されている
  • そのボタン押してもURLアドレスは同じままで、JavaScriptによってページの一部だけが新しく描写され変更される

画像で説明すると、次のような特徴を持つページです。

iframeとJavascirptが使われたページとPythonスクレイピング

方法

考え方

最も根本的な問題点は、

  • ボタンを押してもページの一部分だけが変更されるだけで、ページアドレスが変わらないこと
  • ボタンのリンク属性には、href=”#”

という2点でした。

通常ならば、href=”~”のアドレス部分がわかっていれば、そこにアクセスして・・・という処理が考えられますが、今回は「href=”#”」なので、そこにアクセスしても意味がありません。同じページで同じアドレスのままです。

しかし、ページアドレスは変わらないものの、ボタンを押せばページ内容は変わるので、まずはボタンを押すことが必要です。

そこで「ボタンを押す」→「押した後のHTMLを取得」という処理の流れを考え、次のようなコードを書きました。

コード例(webdriverを使ったもの)とその解説

解決方法は複数あると思いますが、1つの例として以下のようなコードにして解決しました。

なおスクレイピングするための前準備などの処理は省略しました。みなさんの環境にあわせて補ってください。またこのコードでは、webdriver(Chrome版)のメソッドを使っています。

#0 timeモジュールをインポート
import time

#1 webdriverを使う準備などをいろいろ
省略
driver = webdriver.Chrome(省略)
省略

#2 押すべきボタンをXPathを使って特定。それをクリックした後の状態を取得し代入
driver.find_element_by_xpath('//*[@id="XXXX"]/div/ul/li[3]/a').click()

#3 JavaScriptによるHTML書き換えが完了するまで5秒待機(timeモジュールを利用)
time.sleep(5)

#4 今開いているページのHTMLソースを取得し、それをutf-8でencodeして代入
driver_html = driver.page_source.encode('utf-8')

#5 上でつくったオブジェクトdriver_htmlを使った処理をいろいろ
省略~

今回は、まずクリックすべきボタンを特定するためにXPathを使いました。そのXPathを、webdriverのfind_element_by_xpathの引数としています。

このXPathの取得方法は、「【Pythonスクレイピング入門】ChromeとSafariでXpathを取得する方法」で画像入りで説明しましたので、そちらをご覧ください。

そして、特定されたそのボタン要素をクリックすべくclick()メソッドを使っています。

そしてdriver.get()メソッドで、そのクリックされた後の状態にアクセスし、HTMLを取得しています。

ちょっとしたポイントとしては、ボタンクリック後に少しPythonプログラムの実行を待機させるところでしょうか。time.sleep(5)のところです。

これを設定しないと、描写完了後のHTMLソースを取得したいのに、描写が完了される前の、つまり以前のままのHTMLソースを取得することになるかもしれません。今回は待機時間を5秒に設定していますが、みなさんがスクレイプしたいページにあわせて調整してみてください。

プログラミングを学びIT業界へ転職するなら現役エンジニアから学べるプログラミングスクールTechAcademy [テックアカデミー]でオンライン講座を受講するのが良いと思います。1人で悩みながら学習を進めるよりもわかりやすく、費やす時間も少なく合理的・効率的に学習できるからです。

など各種の講座が用意されています。無料で体験できるテックアカデミー無料体験も用意されています。