前回までのあらすじ
これまで基本料金無料だった楽天モバイルが突如無料プランを廃止することを発表――――
UQモバイルをメイン回線、楽天モバイルをサブ回線として使用するスニッチは楽天モバイルを辞めるか回線を変えるか、決断を迫られていたのであった・・・。
- 改めて料金体系調べたら楽天特需に便乗して新料金プランが出まくってた
- 調べ直すのはキツいのでWebスクレイピングで調査した(python併用)
長くなっちゃったので、この記事ではデータ収集の方法だけにします
はじめに
前の記事からずいぶん時間が空いてしまいました😓
お察しの通りフォントだの、テーマだのと現実逃避しまくってたのもそうですが、rlangやtidyselectの勉強に精を出していて、なかなかこの話が進んでませんでした。
ともあれ、前にやりかけた楽天の話をまとめてしまいたいと思います!
調べ直してみたらエラいことに
楽天が無料プランの廃止を発表した直後に各社の料金を手動で調査したのは記事にもしましたが、今頃になって各社新料金を発表し、元楽天ユーザーの獲得に躍起になっているようです
こんな趣味のブログで何時間もかけて調査したのが水の泡とか、もういやんなっちゃったので手軽にデータ収集することにしました。
Webスクレイピングとは?
ということで今回はお手軽データ収集がしたいので、Webスクレイピングの手法を用いることにしました。
Webスクレイピングとは、「Webサイト上の表やテキストをプログラミングで自動取得する技術」のことを言います。
WebスクレイピングはRに限らず様々なプログラミング言語で実行可能ですが、流れは大体同じです。
- スクレイピングしたいWebサイトのソースコード(htmlとcss)を見て、目的の表などを探す
- Webサイトのhtmlをxmlとして取得し、目的部分のcss idを頼りにデータ取得
- 頑張って表形式に整形する
こんな感じ。
専門書等は必要ないですが、以前に私が読んだものだと、以下のものがPrimereadingでタダです。

知識的にはこれくらいで全く問題ないでしょう。
reticulateを使ってpythonとRを融合させる
今回、pythonのpandasライブラリを使った超お手軽スクレイピングを行いたいため、reticulateパッケージでRからpythonを使用します。
reticulateはRからpythonを使用するRパッケージです。Rから純粋なpythonコードを実行させることができるだけでなく、pythonのオブジェクトをRへ渡すことも可能です。
pythonからRを呼び出すことを可能にするrpy2ライブラリもありますが、操作感はreticulateの方が使いやすくて好みです。
データ収集のやりなおし
ということで、自力でデータを集めるのが面倒くさいのでスクレイピングです。
reticulateを使ったスクレイピングを解説しているサイトは見たことがないのですが、もしRでしかスクレイピングをされてないのなら、びっくりするくらい簡単に感じると思います 。
requestsとpandasを使ってスクレイピングする
先にこの操作のコードをお見せします。
基本形は以下です。
# ライブラリ読み込み
pacman::p_load(tidyverse, pipebind, reticulate, magrittr)
scrape_table <- function(url) {
# pythonライブラリの読み込み
pd <- reticulate::import("pandas")
# pd.read_html()を使えば表読み込み操作がこれでおしまい!
return(pd$read_html(url))
}
これで終わりです! たったこれだけで表データがすべて取得できます🧨
簡単でしょう? 🎨🖌️ 私はRの世界からpythonの世界に飛び出したとき、rvestで一所懸命cssタグを探してた苦労は何だったんだろうと思いました😓
Webスクレイピングはマナーを守って行いましょう。ミリ秒単位で多大なアクセスをしてしまうと、対象サイトのサーバーに負荷がかかってしまいます。スクレイピングの際は間隔を開けてアクセス要求をするのがマナーですので、ご注意ください⚠️
これでも多くのサイトでうまくいきますが、稀にスクレイピング目的のアクセスを拒否されることがあるので、アクセス時のヘッダ情報を以下のように書き換えておいた方が安心です。
scrape_table <- function(url) {
# pythonライブラリの読み込み
requests <- reticulate::import("requests")
pd <- reticulate::import("pandas")
# headerをブラウザに偽装
response <- requests$get(
url = url,
headers = dict(
"User-Agent" = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36",
"X-Requested-With" = "XMLHttpRequest"))
return(pd$read_html(response$text))
}
早速この関数を使って、 適当にwikipediaから表を取得してみます。
scrape_table("https://ja.wikipedia.org/wiki/ONE_PIECE")[[7]]
# 発売年 タイトル ジャンル
# 1 2005年 ONE PIECE モバイルジャック ポータルゲームサイト
# 2 2011年 ONE PIECE ARカードダス ARカードダス
# 3 2012年 ONE PIECE グランドコレクション ソーシャルゲーム
# 4 2013年 ONE PIECE アドベンチャーログ ソーシャルゲーム
# 5 2014年 ONE PIECE トレジャークルーズ RPG
# 6 2014年 ONE PIECE DANCE BATTLE リズムゲーム
# 7 2016年 ONE PIECE サウザンドストーム RPG
# 8 2018年 ONE PIECE バウンティラッシュ チーム対戦
# 9 2018年 航海王:燃烧意志(※中国専用) RPG
# 10 2020年 ONE PIECE ボン!ボン!ジャーニー!! パズルゲーム
# ...
# 省略
無事取得できましたね!
ここがRではなく、あえてpythonを使う理由です。pd.read_html()使うと表取得がめっちゃ楽になるのです。これRメインだと知らない人多いと思います。pythonに馴染みが無い方も、pd.read_html()
くらいは知っておいて損はないと思いますよ😄
pythonでは以下のように使いますが、データフレームの扱いはpandasよりもdplyrの方がやりやすいので、紹介した{reticulate}
を使う方法の方がと思います。
import pandas as pd
pd.read_html(url)
ただし、pd.read_html()で取得できるのは表データだけです。それ以外のテキスト等はbeutiful soupというライブラリを使用してスクレイピングするのが一般的です。
reticulateを使うにはpythonパスの指定が必要です。経験上、このパス指定がなーんか直感的に上手くいきにくい印象があります。しかし、Rstudioだと設定画面から驚くほど簡単に変更可能です。
次回予告
今回ご紹介したpd.read_html()
を活用したデータ取得の次、データの前処理(クリーニング)を行います。
そこまでやって初めてデータ可視化、安いキャリアの探索へとつながります。
次回はデータ前処理を行って、ネット上のデータから以下のような表を入手するところまでやります💡
# A tibble: 54 × 5
キャリア data_range price price_exceedable n
<chr> <chr> <dbl> <lgl> <int>
1 ahamo 7-20 2970 FALSE 2
2 ahamo 7-20 2178 FALSE 2
3 au 0-1 2288 FALSE 2
4 au 1-3 2288 FALSE 2
5 au 0-1 3278 FALSE 2
6 au 1-3 4928 FALSE 2
7 HISモバイル 0-1 590 FALSE 2
8 HISモバイル 1-3 590 FALSE 2
9 HISモバイル 0-1 1562 FALSE 2
10 HISモバイル 1-3 2112 FALSE 2
# … with 44 more rows
まとめ
と、言うことで! 短いですが、今回は楽天モバイルの代わりを探すのにはreticulateを使ってpd.readhml()
を活用しながらウェブスクレイピングしてみました!
また空き時間でちまちま書き進めていきますので、次もまた読んでもらえると嬉しいです😃
ではまた~
コメント