ruby define_methodメソッドでコードをシンプルに书く

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby define_methodメソッドでコードをシンプルに书く相关的知识,希望对你有一定的参考价值。

module XpathList
  module Yahoo
    COMPANY_XPATH = {
      name:     "//th[@class='symbol']/h1",
      category: "//table[@class='boardFinCom marB6']/tr[6]/td",
      unit:     "//table[@class='boardFinCom marB6']/tr[13]/td",
    }

    STOCK_XPATH = {
      per: "//div[@class='chartFinance']/div[5]/dl/dd[@class='ymuiEditLink mar0']/strong",
      pbr: "//div[@class='chartFinance']/div[6]/dl/dd[@class='ymuiEditLink mar0']/strong",
      recent_high_price: "//div[11]/dl/dd[@class='ymuiEditLink mar0']/strong",
      recent_low_price:  "//div[12]/dl/dd[@class='ymuiEditLink mar0']/strong",
      high_price: "//div[@class='innerDate']/div[3]/dl/dd[@class='ymuiEditLink mar0']/strong",
      low_price:  "//div[@class='innerDate']/div[4]/dl/dd[@class='ymuiEditLink mar0']/strong",
      price: "//td[@class='stoksPrice']"
    }

    def base_url
      'http://stocks.finance.yahoo.co.jp/stocks'
    end
  end
end
[Rubyを用いてのクローリングについて(6388)|teratail](https://teratail.com/questions/6388) を見て、別の書き方はないものかと試してみたかった

モジュールにハッシュ値の定数を定義する方法にしたけれど、YAML に書き出してそれを読み込む方法もあるかもしれない

<small>(こうした、Web ページを対象にした情報収集は、「あのページを見に行ってこのページに移動して」となるのが辛いところのような気がする)</samll>
require 'nokogiri'
require 'open-uri'
require_relative './xpath_lists'

class CompanyInfo
  include XpathList::Yahoo


  def initialize(ticker_code)
    @stock = stock_info(ticker_code)
    @company = company_info(ticker_code)
  end

  COMPANY_XPATH.each do |key, value|
    define_method(key) do
      @company.xpath(value).text
    end
  end

  STOCK_XPATH.each do |key, value|
    define_method(key) do
      @stock.xpath(value).text
    end
  end

  def print
    puts name
    puts category
    puts unit
    puts 'PER:'        + per
    puts 'PBR:'        + pbr
    puts '年初来高値:' + recent_high_price
    puts '年初来安値:' + recent_low_price
    puts '高値:'       + high_price
    puts '安値:'       + low_price
    puts '株価:'       + price
  end

  private

  def scrape_stock_info(html, index)
    get_content(html, 'dd', 'ymuiEditLink mar0', index, '/strong').delete(',')
  end

  def company_info(ticker_code)
    url = "#{base_url}/profile/?code=#{ticker_code}"
    nokogiri_doc(url)
  end

  def stock_info(ticker_code)
    url = "#{base_url}/detail/?code=#{ticker_code}"
    nokogiri_doc(url)
  end

  def nokogiri_doc(url)
    html = open(url)
    Nokogiri::HTML(html.read, nil, 'utf-8')

  rescue OpenURI::HTTPError
    # empty string
    ''
  end
end

company_info = CompanyInfo.new('4689')
company_info.print
# =>
#   ヤフー(株)
#   情報・通信
#   100株
#   PER:(連) 18.58
#   PBR:(連) 3.47
#   年初来高値:668
#   年初来安値:384
#   高値:428
#   安値:421
#   株価:425

以上是关于ruby define_methodメソッドでコードをシンプルに书く的主要内容,如果未能解决你的问题,请参考以下文章

ruby 超级でスーパークラスのメソッドの返り値とかを操作

ruby 孩子们メソッドとcssで子ノードを全部取るのの违い

python 大熊猫でデータをソートするとき,あるカラムの値を使った行のソート(解りにくい表现ですが,列の内部的ソート)は普通にDataFrame.sore()メソッドでできるのですが,ある行の値を使

ruby 渡したブロックの处理内容にかかわらず,最终的にレシーバを返すメソッド...水龙头

csharp [ワークシートの作成] AddWorksheetメソッドかXLWorkbookインスタンスの工作表プロパティの添加メソッドを使用します。#ClosedXML

ruby 尝试使用实例方法Module#refineお试しでつかってみる。スコープを限定させてクラスのメソッドを改変·拡张するRef:http://www.ruby-doc.org/core