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

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

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

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

Q&A

解決済

1回答

985閲覧

mechanizeで取得した情報に詳細ページへのリンクを設定したい

AkiDatsugoku26

総合スコア35

Ruby on Rails 6

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

0グッド

0クリップ

投稿2021/12/19 03:26

前提・実現したいこと

mechanizeを使用したスクレイピングでグノシーのようなニュースのまとめサイトを制作しています。

情報を取得したいサイトからタイトルや画像を抽出し一覧(index)ページに並べることはできたのですが、
それをクリックし個別の詳細(show)ページに移る方法が分からず質問しました。

controller

1 2class ScrapingsController < ApplicationController 3 def index 4 agent = Mechanize.new 5 page = agent.get("https://xxxxxx.jp/") 6 7 #サムネイル画像を取得 8 @elements = page.search('.news-list .link img') 9 #タイトルを取得 10 @titles = page.search('.caption .title') 11 end 12end

view

1<% @elements.zip(@titles).each do |element, title| %> 2 3 <div> 4 <p><img src= "https://xxxxxx.jp/<%= element.attribute('src').value %>"></p> 5 <p><%= link_to title.inner_text %></p> 6 </div> 7<% end %>

試したこと

繰り返し処理で各投稿を表示することはできているのでそれにIDを付与することができれば、
実現可能だと考えています。

アプローチの仕方で何か良い方法がありましたら是非教えてください。
よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

Rails 6.0.0
ruby 2.6.3

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

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

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

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

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

guest

回答1

0

自己解決

こちら自己解決できましたので共有します。

まず最初にコードです。質問時から大きく変わっている(特にscraping modelを追加している為)ので後から、僕のわかる範囲で補足してみます。

model

1# scraping model 2 3require 'mechanize' 4 5class Scraping < ApplicationRecord 6 7 def self.fuga_urls 8 links = [] 9 agent = Mechanize.new 10 current_page = agent.get("https://xxxxxxxx") 11 elements = current_page.search('.ranking-list .item a') 12 elements.each do |ele| 13 links << ele.get_attribute('href') 14 end 15 16 links.each do |link| 17 get_scraping('https://xxxxxxxx/' + link) 18 end 19 end 20 21 def self.get_scraping(link) 22 agent = agent = Mechanize.new 23 page = agent.get(link) 24 25 title = page.at('.arti-header .head').inner_text 26 image_url = page.at('.figure-area img')[:src] if page.at('.figure-area img') 27 detail = page.at('.arti-body').inner_text 28 29 scraping = Scraping.new(title: title, image_url: image_url, detail: detail) 30 scraping.save 31 end 32end

controller

1class ScrapingsController < ApplicationController 2 3 def index 4 @scrapings = Scraping.all 5 end 6 7 def show 8 @scraping = Scraping.find(params[:id]) 9 end 10end 11

index

1# 一覧画面 2 3<div> 4 <% @scrapings.each do |scraping| %> 5 <p><img src="https://xxxxxxx/<%= scraping.image_url %>"></p> 6 <p><%= link_to scraping.title, scraping_path(scraping) %></p> 7 <% end %> 8</div>

show

1# 詳細ページ 2 3<p><%= @scraping.title %></p> 4<p><img src="https://xxxxxxx/<%= @scraping.image_url %>"></p> 5<p><%= @scraping.detail %></p>

上記のコードで質問時の目的である「mechanizeで取得した情報に
詳細ページへのリンクを取得」することができました。

説明に入る前に大いに参考になった記事を2つ紹介します。
https://qiita.com/takuyanin/items/01256773e1cbfc84f51a
https://chkc.hatenablog.com/entry/2019/07/24/190213

特に2つめの記事はとても役に立つと思います。

今回の問題を解消するために重要なのは下記の2点です。

  • MVCのうち欠けていたスクレイピング用のModelを作成する。
  • スクレイピングで得た情報はデータベースに保存しなければならない

質問時のコードを見ていただければわかると思いますが僕はmodelも作らず、
データベースへの保存もしないまま詳細ページを設定しようとしていました。

「サイトからタイトルや画像を抽出し一覧(index)ページに並べることはできた」
とありますがこれはあくまで対象のデータから情報を抽出して表示させただけにすぎません。
そのため個別のidを持つはずもなく詳細ページへのリンクが設定できることもありません。

モデルでは対象のページの記事のタイトル、画像URL、本文を抽出しています。
前提ではありますが自分の抽出したい情報に合わせてモデルにカラムを追加し、
取り出せるようにしておくことが必要になります。

考えてみればMVCが機能していなかったというとても初歩的な原因だったのですが、
スクレイピングという新しいことに挑戦していたこともあり複雑に考えすぎていたようです。

スクレイピングの記事はタイトルのみの抽出は情報の表示のみを紹介する記事
がほとんどだったのでアウトプットもかねて共有してみました。
誰かの役に立てると嬉しいです。

投稿2021/12/20 15:48

AkiDatsugoku26

総合スコア35

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問