78188


**環境**

ruby 2.7.2  
rails 6.1  
macOS

**前提**

ポートフォリオ作成のため、現在自作アプリを実装しております。  
その中で、DBに必要なデータを保存するため、Rubyのnokogiriでスクレイピングを行なっています。

**エラー内容**

スクレイピングで取得したデータを繰り返し処理でDBに保存している途中、下記のエラーでループが中断、、

[code]

    NoMethodError: undefined method `inner_text' for nil:NilClass
    
[/code]

**解決したいこと**

ループ処理時、取得したいデータが存在しない場合でもループを止めず、次のループに移行する方法が知りたいです。

**試したこと**

データ取得先のサイトを確認した所、アイテムによって取得したいデータが表示されていないページも含まれており、本来値が入るはずだった変数に **nil**
が入ってしまっているのが原因だと分かりました。  
そのため、繰り返し処理の制御構造の`next`を使用することで解決できそうだと感じたのですが、どのように記述すればいいのか分からず、時間だけが溶けている状態です。

詳しい方がいましたら是非アドバイスいただけると幸いです。  
何卒よろしくお願いします。

**該当するソースコード**

`db/schema.rb`

[code]

      create_table "spots", force: :cascade do |t|
        t.string "name", null: false
        t.string "time"
        t.string "location"
        t.text "feature"
        t.string "image"
        t.string "url"
        t.float "latitude"
        t.float "longitude"
        t.integer "area_id"
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.index ["area_id"], name: "index_spots_on_area_id"
      end
    
[/code]

`app/models/scraping.rb`

[code]

    class Scraping < ApplicationRecord
      require 'open-uri'
      require 'nokogiri'
    
      def self.spot_scrape
        base_url = 'https://loconavi.jp/'
        features_url = 'features/hananomeisho'
        url = "#{base_url}#{features_url}"
    
        20.times do |i|
          html = URI.open(url).read
          doc = Nokogiri::HTML.parse(html)
    
          flower_href = doc.css('.flower')[i]["href"]
          next_url = "#{base_url}#{flower_href}"
    
          3.times do |i|
            html = URI.open(next_url).read
            doc = Nokogiri::HTML.parse(html)
            # href属性値の取得(相対URL)。また、_[i]_はtimesメソッドの変数で、繰り返すことに1づつ数値が増えていく
            href = doc.css('.flower-spot')[i]["href"]
            # 相対URLから絶対URLを作成
            link_url = "#{base_url}#{href}"
    
            html = URI.open(link_url).read
            doc = Nokogiri::HTML.parse(html)
    
            doc.css('.main-left-layout').each do | node |
              sleep 1
              # DBに取得したデータを保存
              Spot.create!(
                name: node.at_css('.block').inner_text,
                time: node.css('.spot-info > .t-cell')[1].inner_text,
                location: node.css('.spot-info > .t-row > .t-cell')[1].inner_text,
                feature: node.at_css('.text').inner_text,
                image: node.at_css('img').attribute('src'),
                url: node.at_css('#information p a')["href"]
              )
            end
          end
        end
      end
    
[/code]


CC BY-SA 4.0
2021-07-14T12:03:58.193
78184
2021-07-14T14:33:09.210
2021-07-14T13:33:38.207
32986
46968
question
ruby-on-rails ruby web-scraping nokogiri
取得したいデータが存在しない場合でもループ処理を止めずに次のループに移行する方法が知りたい


事前にnilかどうかチェックして、nilならnextする・・・という対応はいかがでしょうか？

[code]

    doc.css('.main-left-layout').each do | node |
      sleep 1
      
      # データが取得できなかった場合は次のループに行く
      if node.at_css('.block') == nil \
        || node.css('.spot-info > .t-cell')[1] == nil \
        || node.css('.spot-info > .t-row > .t-cell')[1] == nil \
        || node.at_css('.text') == nil then
        next
      end
    
      # DBに取得したデータを保存
      Spot.create!(
        name: node.at_css('.block').inner_text,
        time: node.css('.spot-info > .t-cell')[1].inner_text,
        location: node.css('.spot-info > .t-row > .t-cell')[1].inner_text,
        feature: node.at_css('.text').inner_text,
        image: node.at_css('img').attribute('src'),
        url: node.at_css('#information p a')["href"]
      )
    end
    
[/code]


CC BY-SA 4.0
2021-07-14T14:33:09.210
78188
2021-07-14T14:33:09.210
47298
78184
answer