Help us understand the problem. What is going on with this article?

Railsのnokogiriでスクレイピングしてactiverecord-importで配列をDBに保存する

スクレイピングしてDBに保存したい人向けです

外部からデータ取ってくることに憧れてたので、初めてスクレイピングやった忘備録です。
初めてスクレイピングしたのでおてやわらかにお願いします笑

何をスクレイピングしたの?

paypayのキャンペーンwebページから店舗名を取得しました!
image.png

スクレイピング前のDB

image.png

スクレイピング後のDB

image.png

環境

  • sqlite3
  • ruby 2.6.3
  • Rails 6.0.2.1
Gemfile.
gem 'activerecord-import'
gem 'nokogiri'

bundle installしといてください!

まずはスクレイピングしてみる

今回はcontrollerから呼び出したかったので、moduleとして作成します。

app/controllers/concerns/paypay_scrapes_concern.rb
module PaypayScrapesConcern
  require 'open-uri'
  require 'nokogiri'

  def set_paypay_shops
    url = 'https://paypay.ne.jp/notice/20200604/01/'

    charset = nil
    html = open(url) do |f|
      charset = f.charset
      f.read
    end

    doc = Nokogiri::HTML.parse(html, nil, charset)

    @shops = []

    doc.xpath('//div[@class="article__contents post"]').css('tr').each do |node|
      @shops << node.css("td[1]").text
    end

    @shops = @shops.drop(1)
    p @shops
  end
end

確認したい場合は、app配下直に置いて、ruby paypay_scrapes_concern.rbで確認できます。

表示結果は以下です。

["あさひ", "味千ラーメン 掛川インター店", "遠州屋", "株式会社縁 開縁ダイニング縁や", "大石農場ハム工房", "大手門うおそう", "OZ", "KAKEGAWA 1番地", "掛川グランドホテル", "華月苑", "インド・ネパール料理レストラン GANESHA", "かねきや旅館", "カレー・ザ・ロック", "喜縁旬菜 ZIKAN", "喬菜 まさ吉", "餃子と串カツ 遠州誠家", "串&Bar FuQ(ふく)", "琴菊", "ことのや", "魚処 粋", "椎の木茶屋", "真味楼", "寿し処 八幡", "タナカ", "中国料理四川", "戸塚屋", "巴屋", "ナムズ", "にんちゃんち ", "ひいらぎや", "ファニーファーム", "Food Labo 房’s", "ふらっと", "ベル・エポック", "MAX'S DINER", "まるましらすや", "麺屋 RiQ", "八咫烏", "ラーメン 男前", "らーめん若虎", "LA MAREA 1980 DAN"]

作ったモジュールをcontrollerでincludeしてviewで確認

shops_controller.rb
class ShopsController < ApplicationController

  include PaypayScrapesConcern

  def new
    if params[:format] == "paypay"
      @shops = set_paypay_shops
    end
    @shop = Shop.new
  end
end
new.html.slim
h2 お店を追加する
= render 'form'
= link_to "paypayのキャンペーンを表示する", new_shop_path("paypay")
- if @shops.present?
  - @shops.each do |shop|
    p = shop

localhost:3000/shop/new
↓↓↓↓↓↓
image.png
ボタンを押すと
localhost:3000/shop/new.paypay
↓↓↓↓↓↓
image.png

これでviewで確認できました。

保存用のactionを作成

まずはroutesにactionを追加

routes.rb
resources :shops do
  collection do
    post 'paypay_save'
  end
end

controllerに新しくメソッド追加

shops_controller.rb
def paypay_save
   @shops = set_paypay_shops
   shops = []
   @shops.each do |shop|
     shops << Shop.new(name: shop)
   end
   # DBアクセス一回で配列を保存できるgem activerecord-import
   Shop.import shops
 end

viewも保存用のactionを使えるように設定

new.html.slim
h2 お店を追加する
= render 'form'
= link_to "paypayのキャンペーンを表示する", new_shop_path("paypay")
- if @shops.present?
  // button_toを追加
  = button_to "paypayのキャンペーンショップを追加する", paypay_save_shops_path
  - @shops.each do |shop|
    p = shop

これでviewからキャンペーンショップを追加するボタンを押せば完成です!!

今後はDBのバリデーションとかもやりたいですね。笑

参考

https://morizyun.github.io/blog/ruby-nokogiri-scraping-tutorial/index.html
https://qiita.com/superman9387/items/1981a24664b260e77238
https://qiita.com/makicamel/items/b6d4f3d2661fc66103ed

kotaokubo
大学3年生の文系エンジニアです👨‍💻 学習のメモとして残していきます! よろしくお願いします!
https://note.com/kota_santos
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした