質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

1回答

1526閲覧

【Ruby】クローラーでネットから抜き出した情報が保存されない

Yc_Kz

総合スコア13

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

0クリップ

投稿2017/06/17 09:29

編集2017/06/17 09:36

###前提・実現したいこと
Ruby初心者ですが、
Rubyを使用して、ネットから株価情報を抜き出すシステムを作成しようとしております。
上場市場と売買株数を抜き出し、txtファイルとして保存したいです。

###発生している問題・エラーメッセージ
txtファイルは作成されますが、中身は空のままです。
また、エラーメッセージなどは表示されておりません。

###該当のソースコード

Ruby

1 2 3# coding: Windows-31J 4 5require "open-uri" 6 7# 日経の銘柄情報を取得し、銘柄リストを作るクラス 8# 証券コード、上場市場、単元株数・売買単位が含まれる 9 10class StockListMaker 11 12 attr_accessor :data_dir, :file_name 13 14 15 def initialize(market) 16 17 @market = market 18 @data_dir = "data" 19 @stock_info = [] 20 end 21 22 23 # 銘柄情報の取得 24 25 def get_stock_info(code) 26 page = open_page(code) 27 return unless page 28 text = page.read.encode("Windows-31J" , :undef => :replace) 29 30 data = parse(text) 31 data[:code] = code 32 return unless data[:matket_section] 33 puts code 34 @stock_info << data 35 end 36 37 38 # 銘柄情報の保存 39 40 def save_stock_list 41 File.open(@data_dir + "/" + @file_name, "w") do |file| 42 @stock_info.each do |data| 43 file.puts [data[:code], data[:market_section], data[:unit]].join(",") 44 end 45 end 46 end 47 48 49 private 50 51 # 銘柄情報ページを開く 52 53 def open_page(code) 54 begin 55 open("http://www.nikkei.com" + "/nkd/company/?scode=#{code}") 56 rescue OpenURI::HTTPError 57 return 58 end 59 end 60 61 62 # HTMLから銘柄情報を抜き出す 63 64def parse(text) 65 data = Hash.new 66 67 sections = [] 68 reg_market = /option_mk" >([^< ]+) ?</ 69 reg_unit = %r!<span class="m-stockInfo_detail_value">(\d|,)<span class="m-stockInfo_detail_unit"> 株</span>! 70 71 text.lines do |line| 72 if line = reg_market 73 sections << $+ 74 elsif line =~ reg_unit 75 data[:market_section] = sections[0] 76 data[:unit] = get_unit($+) 77 return data 78 end 79 end 80 data 81end 82 83 84 85# 単元株数を得る 86 87def get_unit(str) 88 if str == "---" 89 "1" 90 else 91 str.gsub(/,/,"") 92 end 93 end 94end 95

Ruby

1# codeing: Windows-31J 2 3require "B:/trade_simulator/lib/stocklistmaker" 4 5 6# 東証銘柄リストを作る 7 8slm = StockListMaker.new(:t) 9 10slm.file_name = ARGV[0] || "tosho_list.txt" 11 12puts slm.file_name 13 14(1400..1402).each do |code| 15 16 slm.get_stock_info(code) 17 18end 19 20slm.save_stock_list

###試したこと
parseメソッドのif end後(下から2つ目のendと3つ目のendの間)で
puts dataを実行すると、

{} {} {} {} {} {} {}

上記のような実行結果が返されます。
このことより、読み込んだデータを保管できていないのかと思っております。

エンコードのせいかと思い、coding:UTF-8でも試しましたが、ダメでした。
正規表現も見直しましたが、わかりませんでした。

###補足情報(言語/FW/ツール等のバージョンなど)
・Ruby 2.3.3
・Eclipseプラットフォーム 4.6.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Ruby

1# encoding: utf-8 2 3require'open-uri' 4require'certified' 5 6def test(code) 7 data = open("http://www.nikkei.com/nkd/company/?scode=#{code}", &:read) 8 9 stock = data.scan(/<span class="m-stockInfo_detail_value\s*">(.+?)<span class="m-stockInfo_detail_unit"> 株/).flatten.first 10 market = data.scan(/<span class="m-company_data_select_btn .+?" data-tab=".m-company_data_option_mk" >(.+?)<\/span>/).flatten.first 11 12 [stock, market] 13end 14 15# ================================= 16# open('market.txt', 'w') do |f| 17# f.puts(test('3197').join("\s")) 18# end 19# ================================= 20 21puts test('3197').join("\s") # => 10,152,600 東証1部 22

考えてみました。

#補足
使い方
3193~3197の「上場市場と売買高」を取得してsample.txtに書き込む場合。

Ruby

1# encoding: utf-8 2 3require'open-uri' 4 5def test(code) 6 data = open("http://www.nikkei.com/nkd/company/?scode=#{code}", &:read) 7 8 market = data.scan(/<span class="m-company_data_select_btn .+?" data-tab=".m-company_data_option_mk" >(.+?)<\/span>/).flatten.first 9 stock = data.scan(/<span class="m-stockInfo_detail_value\s*">(.+?)<span class="m-stockInfo_detail_unit"> 株/).flatten.first 10 11 [market, stock] 12end 13 14(3193..3197).each do |code| 15 open('sample.txt', 'a') do |f| 16 f.puts(test(code).join("\s")) 17 end 18end

企業名と業界を追加したもの

Ruby

1# encoding: utf-8 2 3require'open-uri' 4 5def test(code) 6 data = open("http://www.nikkei.com/nkd/company/?scode=#{code}", &:read) 7 8 title, industry = data.scan(/<meta property="og:title" content="(.+?)"/).flatten[0].split(':').shift(2) 9 market = data.scan(/<span class="m-company_data_select_btn .+?" data-tab=".m-company_data_option_mk" >(.+?)<\/span>/).flatten.first 10 stock = data.scan(/<span class="m-stockInfo_detail_value\s*">(.+?)<span class="m-stockInfo_detail_unit"> 株/).flatten.first 11 12 [title, industry, market, stock] 13end 14 15(3193..3197).each do |code| 16 open('sample.txt', 'a') do |f| 17 f.puts(test(code).join("\t")) 18 end 19end

実行結果例

鳥貴族[3193] 飲食店 東証1部 221,100 キリン堂ホールディングス[3194] 専門店・ドラッグストア 東証1部 51,600 ジェネレーションパス[3195] インターネットサイト運営 マザーズ 22,100 ホットランド[3196] 弁当・デリバリー 東証1部 47,000 すかいらーく[3197] 飲食店 東証1部 10,152,600

投稿2017/06/17 10:19

編集2017/06/18 10:29
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yc_Kz

2017/06/18 09:01

h_a様 回答ありがとうございます。 頂いたコードを既存コードに追加し、 ```ruby # encoding: utf-8 require'open-uri' require'certified' 中略 def open_page(code) begin data = open("http://www.nikkei.com/nkd/company/?scode=#{code}", &:read) rescue OpenURI::HTTPError return end end def parse(text) data = Hash.new sections = [] reg_market = data.scan(/<span class="m-stockInfo_detail_value\s*">(.+?)<span class="m-stockInfo_detail_unit"> 株/).flatten.first reg_unit = data.scan(/<span class="m-company_data_select_btn .+?" data-tab=".m-company_data_option_mk" >(.+?)<\/span>/).flatten.first text.lines do |line| if line = reg_market sections << $+ elsif line =~ reg_unit data[:market_section] = sections[0] data[:unit] = get_unit($+) return data end end data end 後略 ``` と、してみましたが、 `require': cannot load such file -- certified (LoadError) といった形でrequireが上手く作動致しませんでした。 require'certified'をコメントアウトして再度実行したところ、 `get_stock_info': undefined method `read' for #<String:0x00000002274f00> (NoMethodError)と、何故かget_stock_infoメソッドのreadメソッドがエラーになりました。 調べてもよく分からなく、Rubyの最新バージョンに合う良い本も見つからず、せっかくお答え頂いたのに活用出来なく、大変申し訳ありません。 どうぞ、よろしくおねがいいたします。
退会済みユーザー

退会済みユーザー

2017/06/18 10:18 編集

certifiedはopenでエラーが発生する人が使うライブラリなので なくても大丈夫なら無視していただいて構いません。 後からインストールするものなので何もしていなければ存在しません。 私のコードの使い方を追記しました。
Yc_Kz

2017/06/19 21:56

h_a様 回答ありがとうございます。 h_a様のコードを実行してみましたが、invalid multibyte char (utf-8)とエラーが出たので調べてみたら、作成しているRubyファイルの文字コードがUTF-8ではありませんでした。 UTF-8として上書き保存し、実行した所、正常にsample.txtが作成され、情報も記載されておりました。 以上、ベストアンサーとさせて頂きます。 細かくお教えいただき、誠にありがとうございました。
退会済みユーザー

退会済みユーザー

2017/06/19 23:13

いえいえ。どういたしまして。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問