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

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

解決済

1回答

467閲覧

ページを推移させスクレイピングする方法

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グッド

0クリップ

投稿2017/10/03 04:54

編集2017/10/03 05:54

このサイトを参考に1ページ毎にページ推移し、そのページをスクレイピングして、ブラウザ上に表示させたいのですが、うまくいきません。

スクレイピング先の記事一覧は、
https://ameblo.jp/sunsuntaiyo/entrylist.html
https://ameblo.jp/sunsuntaiyo/entrylist−2.html
https://ameblo.jp/sunsuntaiyo/entrylist-3.html



と推移していくようです。

そこで、
1、unless文の中にあるcssで指定されているところはページネーションがemptyかどうかを確認している、という認識でいいでしょうか?
2、attribute('href')のあとにvalueをつける必要はあるのでしょうか?
3、全体としての原因と解決策
の3つを教えていただけたら幸いです。

コントローラー↓

def top require "open-uri" require "nokogiri" blog_id = '' url = "https://ameblo.jp/sunsuntaiyo/entrylist#{blog_id}.html" loop do 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) @titles = [] doc.css("#main > div.skin-blogArchive > div.skin-blogArchiveBody.skin-bgMain > ul > li > div > div:nth-child(2) > h2 > a").each do |row| @titles << row end unless doc.css('.skin-btnIndex').empty? url = doc.css('.skin-btnIndex').attribute('href').value else break end end end

view.html.erb↓

<% @titles.each do |title| %> <div> <a href="<%= title.attr('href') %>"><%= title.text %></a> </div> <% end %>

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

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

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

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

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

guest

回答1

0

ベストアンサー

ruby

1blog_id = '' 2url = "https://ameblo.jp/sunsuntaiyo/entrylist#{blog_id}.html"

は無駄があります。

ruby

1url = "https://ameblo.jp/sunsuntaiyo/entrylist.html"

で十分です。

また

ruby

1unless doc.css('.skin-btnIndex').empty?

はページの作り方を見ると、emptyになる可能性はほぼありません。無限ループに陥ります。

そして、doc.css('.skin-btnIndex')Nokogiri::XML::NodeSetというものが返り値になります。ほぼArrayと思って処理すればよいでしょう。デバッグの際はunless doc.css('.skin-btnIndex').empty?の直前にp doc.css('.skin-btnIndex')などとして、値を見ながらいわゆるプリントデバッグを使えばわかりやすいです。(慣れてくればデバッガを使えばよいですが、おそらくデバッガが使えるくらいになると、本件の問題はやすやすと解決できるようになってます)

あとはページの取得の仕方ですが、設計の方針によります。大まかに、次の2つの方法が考えられますので、頭の体操も含めて考えてみてください。
0. 全てのページのurlを構成してからページを取得する
(ヒント<a href="https://ameblo.jp/sunsuntaiyo/entrylist-646.html" data-uranus-component="paginationEnd" class="skin-paginationEnd skin-btnIndex js-paginationEnd"><span data-uranus-icon="end"></span></a>
0. 1ページごとにページを取得してから遷移していく

#####ここからコメントに応じた追記
スクレイピングは、Rubyの問題より、HTML、CSS、Javascriptを読めるかどうかの方がウェイトが大きいです。

ruby

1#!/usr/bin/env ruby 2# -*- encoding:utf-8 -*- 3 4require 'benchmark' 5require "open-uri" 6require "nokogiri" 7 8def first 9 url = "https://ameblo.jp/sunsuntaiyo/entrylist.html" 10 user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.63 Safari/537.36' 11 12 charset = nil 13 html = open(url, "User-Agent" => user_agent) do |f| 14 charset = f.charset 15 f.read 16 end 17 doc = Nokogiri::HTML.parse(html, nil, charset) 18 page_end = doc.css('.skin-paginationEnd').attribute("href").value.tr('^0-9', '').to_i 19 20 @first = [] 21 1.upto(page_end) do |num| 22 url = "https://ameblo.jp/sunsuntaiyo/entrylist-%d.html"%(num) 23 charset = nil 24 html = open(url, "User-Agent" => user_agent) do |f| 25 charset = f.charset 26 f.read 27 end 28 doc = Nokogiri::HTML.parse(html, nil, charset) 29 doc.css("#main > div.skin-blogArchive > div.skin-blogArchiveBody.skin-bgMain > ul > li > div > div:nth-child(2) > h2 > a").each do |row| 30 @first << row 31 end 32 end 33end 34 35def second 36 url = "https://ameblo.jp/sunsuntaiyo/entrylist.html" 37 user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.63 Safari/537.36' 38 39 @second = [] 40 while url 41 charset = nil 42 html = open(url, "User-Agent" => user_agent) do |f| 43 charset = f.charset 44 f.read 45 end 46 doc = Nokogiri::HTML.parse(html, nil, charset) 47 doc.css("#main > div.skin-blogArchive > div.skin-blogArchiveBody.skin-bgMain > ul > li > div > div:nth-child(2) > h2 > a").each do |row| 48 @second << row 49 end 50 51 url = doc.css('.skin-paginationNext').first.attribute("href") 52 end 53end 54 55Benchmark.bm 15 do |r| 56 r.report "FIRST" do 57 first 58 end 59 r.report "SECOND" do 60 second 61 end 62end 63p @first.size 64p @second.size

投稿2017/10/03 05:45

編集2017/10/05 04:26
NCC1701

総合スコア1680

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

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

renren643

2017/10/03 05:56

すいません、変えました でも、そういったことも含めてあまり理解できていません。
renren643

2017/10/03 06:59

「1ページごとにページを取得してから遷移していく」とは、繰り返し文を使って、1、2、3、・・・・と順にURLの部分に入れていくということですか? 多分全くわかっていないです。 「全てのページのurlを構成してからページを取得する」これに関してはどういうことかさっぱり分かりません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問