8
6

プログラムを書いて趣味環境をちょっと幸せにした話〜初めてのスクレイピング〜

Last updated at Posted at 2023-10-02

私は趣味でとあるカードを集めているのですが、
その数が70枚くらいを超えてから、
どのカードが獲得済みなのか、実際に今何枚なのかを把握するのが大変になってきました。

2年前の私だったら、何度もカード見返したり数えたりすることしかしなかったのでしょうが、
今の私は「情報をどっかから取得して自分のほしい形に整形して管理すればいいじゃない」と言えるようになりました。

そこで、今回は私の集めているマンホールカードの情報を検索サイトの情報を参考にCSVファイルにまとめていきたいと思います。

まさかマンホールカードを知らない人はいないと思いますが、もし万が一知らない場合はこちらのサイトを見てみて下さい。きっと虜になるはずです。

さて、今回は下水道広報プラットフォームの情報を取得し、データを整形、CSV出力していきたいと思います。

なお、今回は個人利用かつ勉強目的でスクレイピングを行っていますが、営利目的で使用する場合などはスクレイピングは行わなず、「マンホールカードのデータ利用に関するガイドライン」に従ってデータの提供を申請するようにして下さい。

マンホールカードのデータ利用に関するガイドライン(以下、単に「ガイドライン」と言う。)は、マンホールカードに関する著作権を有するGKP(下水道広報プラットホーム)と地方公共団体(マンホールカードを製作している地方公共団体を指し、かつ、著作権の対象物は製作したマンホールカードに限るものとする)が、第三者から営利を目的としてマンホールカードに関するデータ(以下「MCデータ」と言い、画像、及び座標等の電子データを指す)の提供を求められた場合に、公共性及び公平性の観点から円滑に手続きを進められることを目的として作成するものです。
なお、当該地方公共団体が自らのマンホールカードのみに関するデータを利用する場合のほか、第三者のうち、企業・団体ではない者が非営利の目的で利用する場合や、報道機関等への提供など明らかにマンホールカード自体のPRに資する場合は、ガイドラインの対象外とします。

コードは以下のとおりです(開発言語はRuby)。

下水道広報プラットフォームのウェブサイトのHTMLを取得し、Nokogiriを使ってHTMLを解析、データを整形し、CSV出力する。というものです。

#
# マンホールカードのまとめサイトにアクセスしてhtmlを取得し、データをCSVで出力
#
def send_csv
    # ウェブサイトのURLを指定
    url = URI.parse('https://www.gk-p.jp/mhcard/?pref=zenkoku#mhcard_result')

    # HTTPリクエストを送信してHTMLを取得
    response = Net::HTTP.get_response(url)
    return unless response.code == '200'

    html_content = response.body
    csv_data = create_csv_data(html_content)

    # エクセルで開くと文字化けするのでSJISでエンコード
    send_data csv_data.encode!(Encoding::SJIS, undef: :replace, replace: '?'),
            type: 'text/csv',
            filename: 'data.csv'
end

#
# CSVデータを作成
#
def create_csv_data(html_content)
    # html_contentをNokogiriで解析
    doc = Nokogiri::HTML.parse(html_content, nil, 'utf-8')

    # 各マンホールカードの情報はtr要素に入っている
    trs = doc.at('table').css('tr')

    csv_data = CSV.generate(row_sep: "\n", encoding: Encoding::UTF_8) do |csv|

      trs.each do |row|
        tds = row.css('td')
        next if tds.blank?

        array = tds.map(&:text)

        # 外部へのリンク
        link = tds.last.css('a').attr('href')&.value
        array.push(link)

        # マンホールカードのイメージソース
        image = row.css('img')[0]['src']
        array.unshift(image)

        csv.add_row(array)
      end
    end
end

出力結果のcsvファイル↓
image.png

始めてNokogiriを使ってみましたが、htmlの解析がこんなに簡単にできるんだ!と驚きました。

プログラミングに触れて、身近な問題の解決策の幅が広がってきた気がして、楽しいなぁと思います。

これで私のマンホールカード収集環境が少し幸せになりましたが、まだまだやりたいこと(slack上で簡易なマンホールカードクイズをするとか、旅行先を入力したら道中で取得できそうなマンホールカードを提案してくれる機能とか...)があるので、
これからもプログラミングの力で趣味環境を整えていきたいと思います。

8
6
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
8
6