【R言語】AKB48の選抜総選挙結果をWebスクレイピング、全員分の画像取得、簡単なグラフ可視化までやってみる

#はじめに

過去3回にわたってスクレイピングしてきた実績を記事にさせていただいたのですが、今回はWebスクレイピング+画像のダウンロード(おまけでグラフ可視化)ということをやっていきたいです。

「何故にAKB?」と思われた方は下の死ぬほどどうでも良い理由を読んでいただくとして、気にならない方はスキップしてWebスクレイピングの項目から読んでください。

####何故AKBなのか?(読まなくていいやつ)

いきなり話が逸れるようで恐縮ですが、ぼくの友達はエロゲーマー3割、無職ヒキコモリ2割、発達障碍者2割、コミュ障2割、キチガイ1割という**狂気の住人達**で構成されていまして、共通して3次元に興味がないという残念な特徴があります。

あまり脱線しすぎるのもよろしくないので詳細は伏せますが、中には**流星街の出身者みたいな奴も珍しくないものでして**、S極とN極の磁石が引かれ合うように、彼ら同士もまた密に繋がりがあります。

先週のことでしょうか。
仲の良いメンツで集まってスマブラしてたのですが、そのうちのメンバー同士が部屋の隅っこに密集して何やら話し合っているのを発見しました。
話しかけるとどうやらAKBネタで盛り上がっていることが判明。
おかしい。**先々月までプリキュアアラモードの再放送で盛り上がっていた**彼らはどこに行ってしまったのでしょうか。
そしてぼくが絶句していると、あろうことかアイドルの布教活動までしてきたわけです。**ぼく一人もわからなかったけどな。**

閑話休題。

長い遠回りをしてしまいましたが、良い友達付き合いを継続していくには時に「相手に合わせる」という処世術を発揮できるよう努力を継続することが肝要です。
いや**アイドルなんて同じ感じじゃない?**って暴言を吐いて戦争に発展しかけたことが理由ではないですよ?趣味を冒涜して怒らせたオタクほどこの世に怖いものはねえなって実感したこととは別に、学習ついでにアイドルのことを少しは知っておくかー、と思った次第ですよ、ほんとに。


##Webスクレイピング

今回、Webスクレイピングの対象となるURLは[45thシングル選抜総選挙の結果](http://www.akb48.co.jp/sousenkyo_45th/result.php)です。

![AKB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/35f95f70-1c5d-f051-ed50-8268c7ecebde.png)

今回取得する項目は…
・名前(name)
・順位(rank)
・得票数(votes)
・チーム(team)
・画像URL(img_path)
・画像名(img_name)

とします。
スクレイピングの部分はこれまでの実績から流用+応用を利かせて取得します。

```r:AKB48.r
# ライブラリ -------------------------------------------------------------------

pacman::p_load(tidyverse,pipeR,rvest,DataExplorer)

# スクレイピング -----------------------------------------------------------------

#読み込む対象のURL
url_txt <- "http://www.akb48.co.jp/sousenkyo_45th/result.php"

#ページの読み込み
data <- read_html(url_txt)

#名前
name <-data %>>%
  html_nodes(xpath = "//h4[@class = 'result_name']") %>>%
  html_text(trim = FALSE)

#順位
rank <-data %>>%
  html_nodes(xpath = "//p[@class = 'result_rank']") %>>%
  html_text(trim = FALSE)

#得票数
votes <-data %>>%
  html_nodes(xpath = "//p[@class = 'result_count']") %>>%
  html_text(trim = FALSE) %>%
  gsub("票","",.) %>%
  gsub(",","",.) %>>%
  as.integer()

#チーム
team <-data %>>%
  html_nodes(xpath = "//p[@class = 'result_team']") %>>%
  html_text(trim = FALSE)

#画像url
img_path <-data %>>%
  html_nodes(xpath = "//p[@class = 'result_img']") %>%
  html_children() %>>%
  html_children() %>>%
  xml_attr("src")
  
#画像名
img_name <- gsub("/sousenkyo_45th/img/_sousenkyo_8th_member_new/jp/image_file/[[:alnum:]][[:alnum:]][[:alnum:]]|[[:alnum:]][[:alnum:]][[:alnum:]]/","",img_path) %>%
            gsub("/sousenkyo_4_sousenkyo_8th_member_jp/image_f[[:alnum:]][[:alnum:]]|[[:alnum:]]/","",.)

df <- tibble(name,rank, votes, team, img_path,img_name)  

#確認用
view(df)
```

取得したい項目をフィールド変数に格納した後、最終的に拡張データフレームのtibbleでデータフレーム化すると以下の結果が得られました(全部で80件あり、画像の22件以降は省略させていただきます)。

![df_akb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/5b210836-2c2a-b5cd-1e50-c26bf4f18086.png)



##AKBメンバー全員の画像をダウンロード

次に、AKBメンバー全員の画像をダウンロードする処理を行います。
AKBフォルダを先につくっておいて、for文で画像パス先の情報をダウンロードする処理、それをメンバー数分だけやればさくっと出来るよネ!と楽観していたら「HTTP404」エラーが発生。

リソースがありませんと怒られた理由は谷口めぐさんだけ画像の命名規則が違っていたというオチだったので、for文の前に対策を取っています。
画像名の規則性が出鱈目で、かつ1000件以上だったら諦めていた…
**AKBは一人も詳しくないんですけど、谷口めぐだけは覚えた**からな。


```r:AKB48.r

# 画像ダウンロード ----------------------------------------------------------------


#谷口めぐだけ画像の命名規則が不規則なので、対策として空白を「%20」に置き換え
df$img_path <- gsub(" ","%20",df$img_path)  

#アイドルの人数分画像をダウンロードする
for (i in 1:length(df$name)) {
  curl::curl_download(paste0("http://www.akb48.co.jp",df$img_path[i]),
                iconv(paste0("AKB",df$img_name[i]),from="utf-8",to="cp932"))  #念のためencode指定
}


```

そして取得した結果がこちら。


![akb_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/3b8a5584-7176-a35c-13fd-afe2cd85197e.png)

やった！

##可視化

最後の仕上げとして可視化を行います。
可視化にはDataExplorerとggplot2パッケージの関数を使って仕上げます。

plot_bar関数を使ってグループごとにおける得票の獲得度数を、ggplot関数で個人の得票実績を可視化しています。

ggplot関数についてはx軸に得票数、y軸に名前を配置するようにcoord_filp()関数でx軸とy軸を反転するよう工夫して見せています。

```r:AKB48.r
# グラフ可視化 ------------------------------------------------------------------

#DataExplorerで可視化
plot_bar(data = df, with = "votes")

df2 <- df %>>%
  group_by(name) %>>%
  tally(wt = votes) %>>%
  arrange(desc(n))

#ggplotで可視化
ggplot(df2,mapping = aes(x=name,y=n)) + 
  geom_bar(stat = "identity") + 
  coord_flip()

```

可視化すると次のようにプロットされます。

plot_bar関数で可視化した結果
![plot_bar_akb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/32be6f7a-f076-4aa6-dd04-3b1006eddacc.png)

ggplot関数で可視化した結果
![ggplot_akb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/e9d306e7-3f86-677a-1cc3-c35e18c45785.png)

AKBグループってこんなに多岐にわたっていたんですね。**ぼく知らなかった**ですけど。
あと個人で指原莉乃の圧倒的強さよ。っていうかAKBってトータルで何人いるんだ。

#おわりに

過去3回にわたってWebスクレイピングチャレンジをしてきました。
これまでの歩みを振り返ればWebスクレイピングの基礎的な部分はだいたい理解できるのではないでしょうか。
これから挑戦される方は参考にしてみてください。
やっていきましょう。

#(参考)これまでのWebスクレイピング
[【R言語】RでWebスクレイピングしてプロット表示するまでをやってみる](https://qiita.com/taro_6974/items/7f28bf071fd33809554b)(1回目)
[【R言語】楽天のレビューデータをスクレイピングしてみた](https://qiita.com/taro_6974/items/da57aabba8d926693ddc)(2回目)
[【R言語】美味いラーメン屋をWebスクレイピングしてみた🍜](https://qiita.com/taro_6974/items/10352110a7659b85502a)(3回目)