【Ruby】HTMLタグからスクレイピングを使ってIDだけぶっこぬく

# 概要
スクレイピング(HTMLパース)を利用して、HTMLタグにあるIDだけを抽出し、CSVファイルに出力。


## 使うに至った経緯

:raising_hand_tone1:Q:どうしてこんな一見誰得な作業を？
:information_desk_person_tone1:A:Seleniumを使うために、HTMLタグからIDを全て抽出できたら楽だよな。って思って。

:raising_hand_tone1:Q:Seleniumって何？
:information_desk_person_tone1:A:今回は特に詳しく解説しないけど、テスト自動化のためのツールだよ。Webサイトにボタンとかテキストボックスとかあるでしょ。あれにIDさえ割り振ればクリックしたり文字入力とかを自動で行うことができるんだ。だけどそのID指定をするためにIDを探さなきゃならない。
Google Chrome付属の開発者ツールで探そうものなら日が暮れちゃうからね。
![すくしょ.png](https://qiita-image-store.s3.amazonaws.com/0/158610/50666166-1e4c-9a65-03ca-0cc130723f14.png)
Firefoxのアドインで、[Selenium IDE](http://qiita.com/showmurai/items/eb9d2a09c584b46727aa)というのがあるから、興味があったらそちらも参考ににした方がいいかな。
話が脱線してしまった。次に行こう。~~今回は詳しく解説しないんじゃなかったっけ・・？~~




## 環境

* :computer:OS：Mac OS10.11.6
* :keyboard:言語：Ruby2.3.0(Ver.2.0.0か2.1.0以上でないとNokogiri使用不可)

## 前提条件
任意のディレクトリ配下に、以下の構成でファイル、フォルダが存在すること

:file_folder:[任意のディレクトリ]
┣:page_facing_up:id_pick_upper.rb(今回使うファイル)
┣:file_folder:inputFile ━ :page_facing_up:適当なファイル
┗:file_folder:outputCSV

※適当なファイル作成は、以下の手順で作業を行うこと
 1. IDを取りたいページで、Google Chrome付属の開発者ツールを開く
 2. \<body>タグで右クリック
 3. Copy -> Copy outerHTMLをクリック
 4. 適当なファイルに貼り付け、そのまま保存する(拡張子は付いても付かなくても良い。~~どうせCSVになるし。~~)


## 事前準備
* :knife:Nokogiriのインストール

```
$ gem install nokogiri
```


## ソースコード
```ruby:id_pick_upper.rb
# coding: utf-8

# Nokogiri, csvライブラリの読み込み
require 'nokogiri'
require 'csv'

# 入出力フォルダ
input = "inputFile"
output = "outputCSV"

# 出力タグ定義
tags = %w(input button div img span select option li)

# フォルダ内部を全て読み込み
Dir::glob("#{input}/*").each do |fname|
    
    # 読み込んだら、Nokogiri使ってパース ※注：ファイルは開いたら閉じましょう。

    doc = open(fname){ |f| Nokogiri::HTML.parse(f, nil, 'UTF-8') }
    # doc = Nokogiri::HTML(IO.read(fname)) # ←こちらでもOK
    
    # 上位ディレクトリ名を除外
    changedFName = File.basename(fname)
    
    # ヘッダー
    CSV.open("#{output}/result_#{changedFName}.csv", "w"){ |csv| csv << %w(tag ID name) }
    
    tags.each do |tag|
        # CSVファイルに、idが存在するタグの分だけを出力
        doc.css("#{tag}[id]").each do |anchor|
            CSV.open("#{output}/result_#{changedFName}.csv", "a") do |csv|
                # 順に、[タグの種類][ID][name属性]を出力している
                csv << %W(#{tag} #{anchor[:id]} #{anchor[:name]})
            end
        end
    end
    
end


```
NokogiriでHTMLをタグベースでぶった切ってそれをcsvにぺぺぺって貼る作業。
(2017/03/22 23:34 追記)
@riocampos さん、 @scivola さん、ご指摘ありがとうございます！
(リファクタリング + 動作確認済み)


## 出力結果
:file_folder:[任意のディレクトリ]
---\(中略)---
┗:file_folder:outputCSV ━ :page_facing_up:result_適当なファイル.csv

[result_適当なファイル.csv]

| tag      |ID | name |
|:--|:--|:--|
| input | ID | inputID |
| input | password | inputPW |
| button  | login | loginBtn |  
| div | inputArea |  |
| div | ： | ： |

## 参考
* [rbenvでのrubyバージョンアップ簡易メモ](http://qiita.com/sue738/items/34e40c032ebbd5ba1737)
* [Rubyでスクレイピング](http://qiita.com/miyasakura_/items/42d9c46f0278d8f7a191)
* [Selenium IDE](http://qiita.com/showmurai/items/eb9d2a09c584b46727aa)
* [RubyでHTML解析が超余裕なんです](http://inobo52.hatenablog.com/entry/2014/09/04/Ruby%E3%81%A7HTML%E8%A7%A3%E6%9E%90%E3%81%8C%E8%B6%85%E4%BD%99%E8%A3%95%E3%81%AA%E3%82%93%E3%81%A7%E3%81%99)

## 所感
* ぶっちゃけ、プログラム云々よりも[Rubyのバージョンアップ](http://qiita.com/sue738/items/34e40c032ebbd5ba1737)の方が難しかった印象
* これで作業効率がかなり上がった気がする。
* ~~requireはfileutilsだけどインストールの時はfile-utilsなのでお気をつけて・・・(めっちゃ詰まった)~~ ← 使うとこなかった。
* if hoge thenが逆nil判定だっていうのに驚き。