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

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

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Ruby

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

2回答

3020閲覧

each文が反映されない

renren643

総合スコア279

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Ruby

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

1クリップ

投稿2017/10/02 16:35

スクレイピングした結果をブラウザ上で表示したいのですが、each文がうまく指定できなく、一行しか帰って
きません。タイトルをブラウザ上で全て表示するようにしたいのですがどうしたいいでしょうか?

ビュー

<% @titles.each do |title| %> <div> <%= title.text %> </div> <% end %>

コントローラ

def top require "open-uri" require "nokogiri" url = "http:〜〜〜〜" user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.63 Safari/537.36' charset = nil html = open(url, "User-Agent" => user_agent) do |f| charset = f.charset f.read end doc = Nokogiri::HTML.parse(html, nil, charset) doc.css(".content").css(".article_box.clearfix").css(".fl_right").each do |row| @titles = row.css("h1").css("a") end end

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

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

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

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

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

guest

回答2

0

ベストアンサー

差支えなければ、スクレピング先のURLは消さないでもらえると間違いが指摘しやすいです。
というのも、doc.css(".content").css(".article_box.clearfix").css(".fl_right")の条件自体が間違っているという可能性もないわけではないからです。
あるいは、htmlをダミーというか動作可能なサンプルにするとか。

動作可能なサンプルのHTMLとは、こういうやつです。
質問に記載しても問題がなく、
今回の条件doc.css(".content").css(".article_box.clearfix").css(".fl_right")に合致するHTMLを考えるわけですね。

html

1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="utf-8" /> 5</head> 6<body> 7<div class="content"> 8 <div class="article_box clearfix"> 9 <div class="fl_right"> 10 <h1><a href="http://example.com/title1">タイトル1</a></h1> 11 </div> 12 <div class="fl_right"> 13 <h1><a href="http://example.com/title2">タイトル2</a></h1> 14 </div> 15 </div> 16</div> 17</body> 18</html>

とりあえず、このHTMLに対して処理するサンプルはこうなると思います。

ruby

1require "nokogiri" 2 3html =<<HTML 4<!DOCTYPE html> 5<html> 6<head> 7 <meta charset="utf-8" /> 8</head> 9<body> 10<div class="content"> 11 <div class="article_box clearfix"> 12 <div class="fl_right"> 13 <h1><a href="http://example.com/title1">タイトル1</a></h1> 14 </div> 15 <div class="fl_right"> 16 <h1><a href="http://example.com/title2">タイトル2</a></h1> 17 </div> 18 </div> 19</div> 20</body> 21</html> 22HTML 23 24charset = 'utf-8' 25doc = Nokogiri::HTML.parse(html, nil, charset) 26 27@titles = [] 28doc.css(".content").css(".article_box.clearfix").css(".fl_right").each do |row| 29 @titles << row.css("h1").css("a") 30end 31 32puts "titles.size=#{@titles.size}" 33@titles.each do |title| 34 puts title.text 35end

実行結果

titles.size=2 タイトル1 タイトル2

コードを見てもらうとお分かりかと思いますが、今回うまく行かない理由は@titlesを配列として各タイトルを格納すべきところを、毎回@titlesを上書きしてしまっているので最後の1件しか入っていないのが原因です。

投稿2017/10/02 19:25

編集2017/10/02 19:28
mingos

総合スコア4025

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

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

renren643

2017/10/03 01:06

回答ありがとうございました。 コントローラーを doc = Nokogiri::HTML.parse(html, nil, charset) @titles = [] doc.css(".content").css(".article_box.clearfix").css(".fl_right").each do |row| @titles << row.css("h1").css("a") end とし、ビューを <% @titles.each do |title| %> <div> <%= title.text %> </div> <% end %> とすることで解決しました。 @titlesを配列にし、each文で生成される新しいタイトルを@titlesの配列に追加する、という処理に変えたらいいんですね。
guest

0

mingos さんのコードをすこし変更してみました。
scan.rb

ruby

1 .... 2charset = 'utf-8' 3doc = Nokogiri::HTML.parse(html, nil, charset) 4 5@titles2 = doc.css('.content').css('.article_box.clearfix').css('.fl_right').map do |row| 6 row.css('h1').css('a') 7end 8puts "titles2.size=#{@titles2.size}" 9@titles2.each { |title| puts title.text } 10 11puts '' 12@titles3 = doc.css('.content').css('.article_box.clearfix').css('.fl_right').css('h1').css('a') 13puts "titles3.size=#{@titles2.size}" 14@titles3.each { |title| puts title.text }

実行結果:

$ ruby scan.rb titles2.size=2 タイトル1 タイトル2 titles3.size=2 タイトル1 タイトル2

titles2 は、 map をつかって配列を生成しています。
titles3 は、nokogiri で直接配列を取得しています。

投稿2017/10/02 23:01

katoy

総合スコア22324

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問