PythonとPhantomJs CloudでスクレイピングしたデータをBeautifulSoupで解析

黒部ダム
みなさん、こんにちは!うえはら(@tifoso_str)です。

JavaScriptで動作するWebページを色々な言語でスクレイピング】するシリーズの第七弾です。

前回は、「PythonでPhantomJs Cloudを利用してWebページをスクレイピング」しました。

PythonでPhantomJs Cloudを利用してWebページをスクレイピング
「JavaScriptで動作するWebページ(動的サイト)を色々な言語でスクレイピング」することをシリーズでお伝えしています。 今回よりPythonとPhantomJsCloudでJavaScriptで動作するWebページをスクレイピングしていきます。

GASと同じように色々な関数があるので、Pythonでも同じような書き方で実行出来ることがわかりました。

GASの場合、この後の処理はJSON形式のパース、matchメソッドと正規表現を使用して目的の値を取得する、という流れでした。

Pythonの場合も同じように、とやってもいいのですが、Pythonにはサードパーティ製のライブラリが豊富にあるので、少し楽できる方法をご紹介します。

今回は、Beautiful Soupというモジュールを利用して、目的のデータを取得していきます。

スポンサーリンク

前回の確認

Beautiful Soupを使う前に前回のおさらいです。
PythonとPhantomJs Cloudでスクレイピングするコードは下記のようになりました。

import json
import urllib.parse
import requests

payload = {'url':'https://www.eb.pref.okinawa.jp/kassui/','renderType':'HTML','outputAsJson':'true'}
payload = json.dumps(payload) #JSONパース
payload = urllib.parse.quote(payload,safe = '') #URIエンコード

key = '**-#####-*****-#####-*****-#####'
url = "https://phantomjscloud.com/api/browser/v2/"+ key+"/?request=" + payload

response = requests.get(url) #GETリクエスト
print(response.text)

リクエスト部分をJSON形式に変換して、URIエンコードしました。

また、URIエンコードするときに「/」スラッシュもエンコードする必要があるので、オプションで指定しました。

GETリクエストして返ってきた実行結果は下記のようでしたね。

Python_実行結果

GASのときと同じようにデータ取得できたので、次の処理へ移っていきます。

JSON形式から辞書型へ変換

Beautiful Soupを使う前にもう少し準備が必要です。

PhantomJs Cloudから返ってきたデータはJSON形式なので、Pythonで扱いやすいように辞書型に変換する必要があります。

JSON形式から辞書型への変換はJSONモジュールを使うのが一般的かもしれませんが、GETリクエストの時に利用したrequestsモジュールでもできます。

今回は、requestsモジュールを使ってみます。

requestsモジュールでJSON形式から辞書型への変換にはjson関数を使い、書き方は下記のようになります。

Responseオブジェクト.json()

はい、とっても簡単ですね!

また、GASで実行したときに「content」の「data」にあることがわかっているので、コードにすると下記のようになります。

import json
import urllib.parse
import requests

key = '**-#####-*****-#####-*****-#####'

payload = {'url':'https://www.eb.pref.okinawa.jp/kassui/','renderType':'HTML','outputAsJson':'true'}
payload = json.dumps(payload) #JSONパース
payload = urllib.parse.quote(payload,safe = '') #URIエンコード

url = "https://phantomjscloud.com/api/browser/v2/"+ key+"/?request=" + payload

response = requests.get(url) #GETリクエスト

responseDict = response.json()
html = responseDict["content"]["data"]
print(html)

実行結果を確認すると以下のようになります。

Python_HTMLドキュメント

つらつらとHTMLドキュメントが取得できたと思います。

Beautiful Soupを使って目的の値を取得

HTMLドキュメントが取得できたので、いよいよBeautiful Soupモジュールを使っていきます。

Beautiful Soupモジュールは標準ライブラリではないので、インストールが必要です。

Beautiful Soupモジュールのインストール等は下記の記事で紹介しているので、こちらをご覧下さい。

Pythonで取得したWebページのHTMLを解析するはじめの一歩
初心者かつWindowsユーザー向けにPythonでWebスクレイピングをする方法についてお伝えしています。今回はPythonでWebページのHTMLを解析するはじめの一歩、Beautiful Soupモジュールの使い方です。

HTMLドキュメントを解析するには、まず、HTMLドキュメントからBeautifulSoupオブジェクトを作成する必要があります。

この作業をBeautiful Soupのドキュメントでは、スープの作成と呼んでいます。(本当です!)

Beautiful Soup — Beautiful Soup 4.12.0 documentation 日本語版

BeautifulSoupオブジェクト(スープ)の作成は下記のようになります。

bs4.BeautifulSoup(HTMLドキュメント, パーサー)

パーサーの部分でどのような形式で解析するか決めます。

lxmlやhtml5libという形式がありますが、今回は標準ライブラリのhtml.parserを使用します。

実際には下記のようなコードになります。

soup = bs4.BeautifulSoup(html, "html.parser")

BeautifulSoupオブジェクト(スープ)が作成できたら、あとは目的の値を取得するだけです。

タイトルの取得

まずは、タイトルを取得してみます。

BeautifulSoupオブジェクトから特定のタグ要素を取得するには、下記のようになります。

BeautifulSoupオブジェクト.タグ名

タイトルを取得するにはタグ名を「title」にすればいいので、コードは下記のようになります。

import json
import urllib.parse
import requests
import bs4

key = '**-#####-*****-#####-*****-#####'

payload = {'url':'https://www.eb.pref.okinawa.jp/kassui/','renderType':'HTML','outputAsJson':'true'}
payload = json.dumps(payload) #JSONパース
payload = urllib.parse.quote(payload,safe = '') #URIエンコード

url = "https://phantomjscloud.com/api/browser/v2/"+ key+"/?request=" + payload

response = requests.get(url) #GETリクエスト

responseDict = response.json()
html = responseDict["content"]["data"]

soup = bs4.BeautifulSoup(html, "html.parser")
print(soup.title)

実行してみます。

Python_TitleのHTML要素

取得できましたが、これは、HTML要素を表すTagオブジェクトです。

実際には、テキスト部分を抜き出したいですよね!

そんなときは、追加でgetTextメソッドを使用します。

Tagオブジェクト.getText()

先程のコードの20行を下記のように変更します。

print(soup.title.getText())

実行すると、下記のようにタグの中身だけを抜き出せます。

Python_Titleのテキスト

id属性で値を取得

次はid属性で値を取得してみます。

id属性は一つのページに一つしかないので、id属性がわかっていれば、簡単に値を取得できます。

BeautifulSoupオブジェクトからCSSセレクタを使って、Tagオブジェクトを取得するにはselectメソッドを使用します。

id属性から取得するには下記のようになります。

BeautifulSoupオブジェクト.select(#id名)

今回は日付のidは「chosui_hiduke」貯水率のidは「ritsu_today4」なので、コードは下記のようになります。

import json
import urllib.parse
import requests
import bs4

key = '**-#####-*****-#####-*****-#####'

payload = {'url':'https://www.eb.pref.okinawa.jp/kassui/','renderType':'HTML','outputAsJson':'true'}
payload = json.dumps(payload) #JSONパース
payload = urllib.parse.quote(payload,safe = '') #URIエンコード

url = "https://phantomjscloud.com/api/browser/v2/"+ key+"/?request=" + payload

response = requests.get(url) #GETリクエスト

responseDict = response.json()
html = responseDict["content"]["data"]

soup = bs4.BeautifulSoup(html, "html.parser")
print(soup.title.getText())
print(soup.select('#chosui_hiduke').getText())
print(soup.select('#ritsu_today4').getText())

実行してみます。

Python_日付取得エラー

あれ、エラーが出てしまいましたね。

エラー内容を確認すると、「リストオブジェクトにはgetTextメソッドは使用できません。」となっています。

selectメソッドは複数の値を取得できるように、リスト形式でデータが返ってくるんですね。

リストであることを考慮してコードを修正します。

import json
import urllib.parse
import requests
import bs4

key = '**-#####-*****-#####-*****-#####'

payload = {'url':'https://www.eb.pref.okinawa.jp/kassui/','renderType':'HTML','outputAsJson':'true'}
payload = json.dumps(payload) #JSONパース
payload = urllib.parse.quote(payload,safe = '') #URIエンコード

url = "https://phantomjscloud.com/api/browser/v2/"+ key+"/?request=" + payload

response = requests.get(url) #GETリクエスト

responseDict = response.json()
html = responseDict["content"]["data"]

soup = bs4.BeautifulSoup(html, "html.parser")
print(soup.title.getText())
print(soup.select('#chosui_hiduke')[0].getText())
print(soup.select('#ritsu_today4')[0].getText())

Python_スクレイピング結果

はい、無事に目的の値を取得できました。

まとめ

今回はPythonとPhantomJs CloudでスクレイピングしたデータをBeautifulSoupで解析しました。

GASでは正規表現とmatch関数を使用した部分を、PythonではBeautifulSoupを利用することで、コードをスッキリとすることが出来ました。

VBA,GAS,Pythonと3つの言語でスクレイピングしました。

使いやすい言語で、スクレイピングにチャレンジしてみて下さい!

連載目次:JavaScriptで動作するWebページを色々な言語でスクレイピング

Webスクレイピングしていて、値が取得できないということはありませんか?

そんな時は、Webサイトの表示にJavaScriptを利用しているからです。

本連載では、色々な言語でその対応をご紹介します!

  1. GASやVBAでスクレイピングができない理由として考えるべきJavaScriptのこと
  2. VBAでIEを操作してJavaScriptで動作するWebページをスクレイピング
  3. GASでJavaScriptで動作するWebページをスクレイピングするPhantomJsとは
  4. GASでPhantomJSを利用してWebページをスクレイピング
  5. GASでスクレイピングしたデータからmatchメソッドと正規表現を使って目的の値を取得
  6. PythonでPhantomJs Cloudを利用してWebページをスクレイピング
  7. PythonとPhantomJs CloudでスクレイピングしたデータをBeautifulSoupで解析
タイトルとURLをコピーしました