9
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Power BIでWebスクレイピングを行う

Last updated at Posted at 2020-12-09

本記事の目的

コロナ禍に対して、国や都道府県だけでなく各市区町村も、消費活動を活発化させるための様々なキャンペーンを実施しています。鎌倉市では地元の店舗で利用可能な商品券を市民に配布する「縁結びカード」という事業が実施されています。

鎌倉応援買い物・飲食電子商品券「縁(えん)むすびカード」事業
https://www.enmusubi-card.com/
image.png

利用できるのは地元の飲食店くらいかと思いきや、業種一覧を見てみると「建設業」(!?)なども入っています。2020年12月9日時点での利用可能な店舗数は1,200程度とかなり多くあり、利用者としては有難い限りです。

ただ、実際に利用できる店舗を検索しようとすると、こんな感じの表になっていて正直見づらい...。「近所で利用できる店舗ないかな」と思うと、近くの町名を順番に入れていって検索するしかなさそうです。

image.png

1ページあたり最大18店舗分の情報があり、これ以降はページ送りしながら順番に見ていくことになります。
現時点で全部で67ページほどあるので、これを全部見ていくのは骨が折れます。

image.png

そこで今回は、縁むすびカードの対象店舗の一覧をマップ上にプロットすることを考えたいと思います。

結論だけ先に書きます。

  • Power BIを使って「縁むすびカード」の対象店舗の情報をウェブスクレイピングできる
  • 住所情報を含むリストがあれば、Google Maps上に対象店舗の情報をプロットできる

できたマップはこんな感じです。
https://www.google.com/maps/d/edit?mid=1I7WiAAm5JBOzZM1dF--9hVRJDTDxyAZU&usp=sharing
image.png

アプローチ

以降、2段階でのアプローチを考えます。

  1. ウェブサイトからの情報取得(ウェブスクレイピング)を行う
  2. 取得した情報を地図上にプロットして整理する

1. ウェブスクレイピング(Power BI)

まずはWebサイトから必要なデータを集めてくる部分ですが、これは色々な方法があります。

  • UiPathやautomation anywhereなどのRPA
  • Python (requestsやbeautifulsoup)
  • ExcelのVBA
  • Power BIのWebコネクタ

別にどれを使っても良いのですが、「もしかしてPower BIであればそのまま可視化(マップ化)までできるのでは?」という淡い期待があり、今回はPower BIでのウェブスクレイピングを試してみました。

以下ではその具体的な方法について紹介します。

1ページ分の情報を取得

まずは単純に「Webコネクタ」を使って今回の対象URLから情報を取得します。
対象URL: https://www.enmusubi-card.com/list/?n=&t=&c=&page=1
image.png

image.png
この時点で既に、ページからちゃんとHTML構造を把握してデータを取得してきてくれていることが分かります。
「データの変換」を押して、次の処理に進みましょう。
(もし「読み込み」を押してしまったら、画面上の「データの変換」を押せばOKです)

複数ページ分の情報が取得できるようにパラメータ化した関数をつくる

先ほどはURLを決め打ちで指定しましたが、実際には複数のページからデータを取得します。Webページを確認すると、単純なルールで複数ページのURLが取得できることが分かります。そこで末尾の数字の部分をパラメータ化しておきます。

画面上部のリボンにある「詳細エディター」を開きます。
image.png

するとWeb.BrowserContentsを使って、指定のURLが開かれていることが分かります。
image.png

ここに変数「page」が利用できるようにするために以下のように書き換えます。

編集前
let
    ソース = Web.BrowserContents("https://www.enmusubi-card.com/list/?n=&t=&c=&page=1"),
    #"HTML から抽出されたテーブル" = Html.Table(ソース, {{"Column1", ".category"}, {"Column2", "H3"}, {"Column3", "P"}, {"Column4", ".address"}, {"Column5", ".tel"}, {"Column6", ".hours"}, {"Column7", ".closed"}, {"Column8", ".btDetail *"}, {"Column9", ".exLink"}}, [RowSelector=".listBox"]),
    変更された型 = Table.TransformColumnTypes(#"HTML から抽出されたテーブル",{{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", type text}, {"Column7", type text}, {"Column8", type text}, {"Column9", type text}})
in
    変更された型
編集後
(page as number) => 
let
    ソース = Web.BrowserContents("https://www.enmusubi-card.com/list/?n=&t=&c=&page="& Number.ToText(page)),
    #"HTML から抽出されたテーブル" = Html.Table(ソース, {{"Column1", ".category"}, {"Column2", "H3"}, {"Column3", "P"}, {"Column4", ".address"}, {"Column5", ".tel"}, {"Column6", ".hours"}, {"Column7", ".closed"}, {"Column8", ".btDetail *"}, {"Column9", ".exLink"}}, [RowSelector=".listBox"]),
    変更された型 = Table.TransformColumnTypes(#"HTML から抽出されたテーブル",{{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", type text}, {"Column7", type text}, {"Column8", type text}, {"Column9", type text}})
in
    変更された型

変更点は2点

  1. 冒頭に(page as number) =>を追記
  2. page=1の代わりにpage=& Number.ToText(page)

これで与えられたパラメータ(page)に対する情報を取得できるようになりました。実際にパラメータとして例えば10(=10ページ目)を入力して「呼び出し」を押すと、正しく10ページ目の取得ができるようになりました。
image.png
image.png

パラメータを準備する

あとは利用するパラメータ(page)を準備するだけです。画面左の「クエリ」部分を右クリックして、空クエリから新しいクエリを作成しましょう。

image.png

新しいクエリで={1..100}などとすれば、1から100の連続値を持ったリストが作成できます。
今回は取得したいページ数は1~67ですが、今後ページ数が増えることも見越して100までの連続値を作りました。
image.png

この後の処理のために、リストをテーブルに変換しておきます。
image.png

作成したパラメータと関数を使ってデータを収集する

先ほど複数ページ分の情報が取得できるようにパラメータ化した関数をここで呼び出します。
image.png
image.png

これでOKをおせば、1行目には1ページ目の情報、2行目には2ページ目の情報が入った形で表が作成されます。
この時点でデータを取得してきている(Webスクレイピングしている)ので、しばらく時間がかかります。

image.png

あとは列の展開をすればOKです。
何も値が取得できなかったページ(今回で言えば68ページ以降)に対しては値がnullになっていますが、不要なのでnullの行は削除するように加工しておきましょう。

image.png

無事にPower BIに店舗一覧のデータが取り込めたので可視化してみたいのですが、今回のような自由記述の住所に対して、Power BIのビジュアルでうまくプロットすることはできなさそうでした。

そこで今回は整形したデータだけcsv形式で取得しておき、Google Mapsを用いて地図を作りたいと思います。
image.png

2. 地図へのプロット(Google Maps)

ここからはおまけですが、Googleマップの機能で「マイマップ」を使っていきます。

https://www.google.co.jp/intl/ja/maps/about/mymaps/
image.png

「新しい地図を作成」から「インポート」した後は指示通りに進んでいくだけです。
image.png

業種ごとにグループ化してあげればこんな感じで見えます。
image.png

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?