ogpの情報を取得したい
nokogiriを利用したスクレイピング
アプリ制作に伴いogpの情報を自分のアプリ内で表示したいと思って調べました。
今回はurlを登録するとそのサイトのmetaタグから情報を取得して、データベースに保存するサンプルを作ります。
環境
導入
rails newの雛形作成直後を例に進めます。
hogeモデルとコントローラーを作ります。後からカラムを追加するのは余計なフォームができるのを避けるためです。
bundle install rails g scaffold hoge url:string rails g migration AddColumnToHoges title:string description:string rails db:migrate
バリデーション等考慮すべきですが、今回は動作確認が目的なので省略。
これでURLを登録するフォームができました。
次にスクレイピング部分を実装します。わかりやすいようにいったんcreateアクション内で全て行います。
def create require 'open-uri' @hoge = Hoge.new(hoge_params) html = URI.open(@hoge.url).read doc = Nokogiri::HTML.parse(html) @hoge.title = doc.css('meta[property="og:title"] @content').to_s @hoge.description = doc.css('meta[property="og:description"] @content').to_s 以下略
require 'open-uri'
でrubyのライブラリを読み込み。URI.openによりファイルを開くような感覚でhttp/ftpにアクセスできます。
openメソッドでサイトにアクセスし、readメソッドでデータを読込んで内容を変数に保存。
Nokogiri::HTML.parse(html)
により取得したデータをパースする。その後cssメソッドで取得したい情報を選択して各属性に保存。
参考記事ではrailsを使用しないrubyファイルだったのでnokogiriのrequireをしていましたが、railsの場合はインストールされているのでなくても使用できました。
https://zenn.dev/arao99/articles/40cde7168279f899d0f5
データ検索条件についてはcssセレクタとxpathを使用する方法があり、検索するメソッドもたくさんありました。
https://nokogiri.org/rdoc/Nokogiri/XML/Searchable.html#css-instance_method
ogpについては記載方法が決まっているようなので上記のような方法だと設定されている場合は取得できるはず。
https://ogp.me/
viewに表示部分を追加します。
<p><%= @hoge.title %></p> <p><%= @hoge.description %></p>
続いて画像の保存部分です。 active storageを使用して保存してみます。最初にインストールを行います。
rails active_storage:install
これにより必要なテーブルを作成するためのマイグレーションファイルが生成されます。 保存先はデフォルトではこんな感じです。 config/strage.yml
test: service: Disk root: <%= Rails.root.join("tmp/storage") %> local: service: Disk root: <%= Rails.root.join("storage") %>
config/environments/development.rbに設定の読み込みを追加します。
config.active_storage.service = :local
画像の加工をしたいのでGemfileの中のimage_processingのコメントを解除してbundle installします。
gem 'image_processing', '~> 1.2'
マイグレーションとgemのインストールを行ったのでサーバー起動中の場合は再起動します。
class Hoge < ApplicationRecord has_one_attached :image end
モデルに関連付けを追加。 createアクションに処理を追加します。
image = doc.css('meta[property="og:image"] @content').to_s @hoge.image.attach(io: URI.open(image), filename: image)
viewに表示を追加
<div class=""> <%= image_tag @hoge.image.variant(resize: "200x200") %> </div>
active storageの使用方法はrailsガイドの記載を参考にしました。 https://railsguides.jp/active_storage_overview.html
これで取得した画像を保存、表示することができました。
URI.openのアクセスについては503エラーとなるサイトがありました。その場合はユーザーエージェントに関する記述を追加すれば同様の処理ができましたが、あまりわかっていないので割愛します。
また、スクリプトによる連続アクセスは攻撃とみなされトラブルになることもあるそうなので気をつけて使用する必要があるとのことでした。
あとは取得した情報を元にCSSを設定すると好みの見た目でリンクを表示できそうです。