기상청 데이터를 루비로 스크래핑

프로그래밍 스쿨을 졸업하고 뭔가 스스로 만들고 싶었습니다.
이런 경우에는 자신이 사용하고 싶은 앱을 만드는 것이 동기 유지를 위해 중요할 것입니다.
현재 농업 컨설팅 업무에 종사하고 있으므로 농가가 항상 확인하는 날씨 정보를 보다 유용한 형태로 표시하는 앱을 만들기로 했습니다.

기상청의 과거 기상 데이터 활용



이번 활용하는 데이터는 이쪽입니다.
기상청 웹페이지에는 과거 기상 데이터가 공개되어 있어 누구나 활용할 수 있습니다.

표시 방법은 2개.
  • CSV 데이터로 다운로드
    h tp // w w. 했다. j. . jp/gmd/리 sk/오 bsdl/그리고 x. php
  • 웹으로 보기
    h tp // w w. 했다. j. . jp / 오 bd / s ts / 에 trn / ぃえ w / 대 ly_s1. php? p c_의 = 20&bぉck_의 = 47417&아아 r=2019&몬 th=12&다 y=26&ゃぃえw=

  • 여기서는 2. 웹에서 표시한 데이터를 스크래핑으로 검색합니다.

    Mechanize



    루비로 간단하게 스크레이핑을 할 수 있는 gem입니다.
    gem 'mechanize'
    

    기본적인 사용법은 다음과 같습니다.
    
    #Mechanizeクラスのインスタンスを生成する
    agent = Mechanize.new
    #Mechanizeクラスのインスタンスメソッドget(情報を取得したいウェブサイトのURL)で、ウェブサイトのHTML情報を取得する
    page = agent.get("https://www.data.jma.go.jp/〜")
    #欲しいデータのあるタグ要素をsearchメソッドで指定して取得する
    elements = page.search('a')
    #取得したタグ要素のHTML情報にたいしてinner_textメソッド、またはget_attributeメソッドを使って欲しい値を取得する
    text = elements.inner_text()
    url = elements.get_attribute(:href)
    

    참고
    htps //w w. 하는 by c. 인후 / 게 ms / 엄청나게 / 엄청나게
    ㅡㅡㅡㅜㅜㅜㅜㅜㅜㅜㅜㅜ jp / ru by _ 엄청 / d / 엄청

    기상 데이터 스크래핑



    여기에서 본제의 기상청 데이터를 스크래핑하는 방법입니다.

    1. URL 해독
    
    require 'mechanize'
    require "date"
    
    class WetherScraping
      attr_reader :prec_no, :block_no, :date, :url
    
      # is_nomal = true ⇨ 平年値のページをスクレイピング false指定年月日のページをスクレイピング
      def initialize(prec_no,block_no,date,is_nomal = false)
        @prec_no = prec_no
        @block_no = block_no
        @date = date
        @is_nomal = is_nomal
        if @is_nomal
          @url = "https://www.data.jma.go.jp/obd/stats/etrn/view/nml_sfc_d.php?prec_no=#{@prec_no}&block_no=#{@block_no}&year=#{@date.year}&month=#{@date.month}&day=#{@date.day}&view="
        elsif !@is_nomal
          @url = "https://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=#{@prec_no}&block_no=#{@block_no}&year=#{@date.year}&month=#{@date.month}&day=#{@date.day}&view="
        end
        agent = Mechanize.new
        @@page = agent.get(@url)
        @@head_tr = @@page.search('//*[@id="tablefix1"]/tr[1]')
        @@heads_ths = @@head_tr.search('th')
      end
    
      # innner_text 未入力の場合は全coloum数、innner_textを入れればそこまでのcoloum数を返す
      def get_coloum_index(inner_text = "")
        colsum = 0
        @@heads_ths.each do |th|
          return colsum if inner_text != "" && th.inner_text() == inner_text
          colspan = th.get_attribute(:colspan).to_i
          colspan = 1 if colspan == 0
          colsum += colspan
        end
        return colsum
      end
    
      def get_row_length()
        table = @@page.search('//*[@id="tablefix1"]/tr')
        table.size
      end
    
      def start_row
        if @is_nomal
          row = 4
        else
          row = 5
        end
        return row
      end
    
      def get_coloum_texts(colum_num, row_length)
        row = start_row()
        texts = []
        while row <= row_length
          row_children_XMLs = @@page.search("//*[@id=\"tablefix1\"]/tr[#{row}]").children
          row_texts = []
          row_children_XMLs.each do |child|
            row_texts << child.inner_text()
          end
          texts << row_texts[colum_num] unless row_texts[colum_num].size == 0
          row += 1
        end
        return texts
      end
    
      def get_value(coloum_num)
        colvalues = get_coloum_texts(coloum_num, get_row_length())
        colvalues[@date.day - 1]
      end
    
    end
    

    좋은 웹페이지 즐겨찾기