ruby 配列で数字を+1ずつ増やしたい
- 評価
- クリップ 1
- VIEW 1,310
vod1 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[n])
@vod1 = vod1.map{|a| a.attribute('alt')}
vod1の最後のnの部分を+1ずつ増えるようにしたいのですが、どのように書けばいいのでしょうか?
<% if @arrays.present? %>
<% @arrays.each do |array| %>
<br>
<div><%= array["title"] %></div>
<br>
<div><%= image_tag 'https://image.tmdb.org/t/p/w500'+array["poster_path"] %></div>
<br>
<div><%= array["overview"] %></div>
<br>
<div><%= array["release_date"] %></div>
<% if @vods.present? %>
<p><%= @vod1 %></p>
<% if @vod2.present? %>
<p><%= @vod2 %></p>
<% end %>
<% if @vod3.present? %>
<p><%= @vod3 %></p>
<% end %>
<% if @vod4.present? %>
<p><%= @vod4 %></p>
<% end %>
<% end %>
<% end %>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2018/10/24 12:32 編集
n = 10
(1..n).each { |i|
vod1 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[i]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[1]/div/a/div/img')
vod2 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[i]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[2]/div/a/div/img')
vod3 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[i]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[3]/div/a/div/img')
vod4 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[i]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[4]/div/a/div/img')
}
doc = Nokogiri::HTML.parse(driver.execute_script('return document.documentElement.innerHTML'))
# 検索結果のタイトルを表示
doc.xpath('/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]').each do |node|
@vod1 = vod1.map{|a| a.attribute('alt')}
@vod2 = vod2.map{|a| a.attribute('alt')}
@vod3 = vod3.map{|a| a.attribute('alt')}
@vod4 = vod4.map{|a| a.attribute('alt')}
このようにしてみたのですが、undefined local variable or method `vod1'
こういったエラーになってしまうのですが、書き方がおかしいのでしょうか?
2018/10/24 12:36
どういう使い方をしたいのかわからないのですが、ループ内で完結させるかviewにわたすなら@vod1などを配列にするのが良いかと。
2018/10/24 12:49
view
<% if @arrays.present? %>
<% @arrays.each do |array| %>
<br>
<div><%= array["title"] %></div>
<br>
<div><%= image_tag 'https://image.tmdb.org/t/p/w500'+array["poster_path %></div>
<br>
<div><%= array["overview"] %></div>
<br>
<div><%= array["release_date"] %></div>
<% if @vods.present? %>
<p><%= @vod1 %></p>
<% if @vod2.present? %>
<p><%= @vod2 %></p>
<% end %>
<% if @vod3.present? %>
<p><%= @vod3 %></p>
<% end %>
<% if @vod4.present? %>
<p><%= @vod4 %></p>
<% end %>
<% else %>
<p>配信しているvodはありません!!</p>
<% end %>
<% end %>
<% end %>
表示する情報を変えたいと思っています。
2018/10/24 12:50
2018/10/24 12:53 編集
vod1 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[1]/div/a/div/img')
としていてdiv[1]しか取得できないので数字を配列ごとにdiv[2],div[3]と変えたいと思っています。
2018/10/24 12:57
controller側でループで数値を変えても、同じ変数に入れてる限りは最後の値しか格納されません。
view側を見る限りループさせているわけでもなさそうですし、どう表示したいのかがいまいち伝わってないです。
2018/10/24 13:08
例. 現在 検索名「ゴジラ」
作品名「ゴジラ」
vod[amazonプライム]
作品名「ゴジラ2」
vod[amazonプライム]
作品名「ゴジラ3」
vod[amazonプライム]
理想
作品名「ゴジラ」
vod[amazonプライム]
作品名「ゴジラ2」
vod[hulu]
作品名「ゴジラ3」
vod[Netflix]
こういう風にしたいのですが、全部amazonプライムになってしまうという状態です。
2018/10/24 13:18 編集
2018/10/24 13:18
なのにcontroller側で@vod1などのように設定したら@arrayに関係ないのは当然ではないでしょうか?
やるのであれば@arrayのように配列で同じ順で格納するとか@arrayの各要素に追加するとかになります。
2018/10/24 13:32
@vod1がおかしいのでしょうか?
@vod1はseleniumで指定したxpathのalt属性を表示するという処理を入れているのですが、いまいちどうすればいいかわかりません。
view をいじるのでしょうか?
2018/10/24 13:38
vod1は | X | と1つ分しか格納できないので、いくらcontroller側で
void1 = ...div[i]...
としても1作品分しか格納できません。
A作品のvod、B作品のvod...というようにしたいのなら
vod1も | X | Y | Z | W | のように配列で格納するか
元のarrayに | A,X | B,Y | C,Z | D,W | のようにしないとダメです。
2018/10/24 14:33 編集
def index
require 'uri'
require 'net/http'
require 'json'
@name = params[:name]
a = URI.encode("https://api.themoviedb.org/3/search/movie?api_key=!!&language=ja&query="+@name.to_s)
url =URI(a)
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(url)
request.body = "{}"
response = http.request(request)
hash= JSON.parse(response.body)
@arrays = hash["results"]
require 'selenium-webdriver'
require 'nokogiri'
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = Selenium::WebDriver.for :chrome, options: options
driver.navigate.to 'https://www.justwatch.com/jp/検索?q=' +@name.to_s
wait = Selenium::WebDriver::Wait.new(timeout: 300)
wait.until { driver.find_element(xpath: '//div[2]/filter-bar/div[2]/div[2]/div[3]/div[2]/div',) }
vod1 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[1]/div/a/div/img')
vod2 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[2]/div/a/div/img')
vod3 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[3]/div/a/div/img')
vod4 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[4]/div/a/div/img')
doc = Nokogiri::HTML.parse(driver.execute_script('return document.documentElement.innerHTML'))
# 検索結果のタイトルを表示
doc.xpath('/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]').each do |node|
@vod1 = vod1.map{|a| a.attribute('alt')}
@vod2 = vod2.map{|a| a.attribute('alt')}
@vod3 = vod3.map{|a| a.attribute('alt')}
@vod4 = vod4.map{|a| a.attribute('alt')}
@vods = [@vod1, @vod2, @vod3, @vod4]
end
driver.quit
end
view
<p><b>Hulu, U-NEXT,dtv,GYAO!,Amazonprime,Netflixの中から配信中のvodを見つけられます!</b></p>
<%= form_tag({action: :index}, {method: :get}) do %>
<br>
<%= label_tag :name, '作品名' %>
<%= text_field_tag :name, @name %>
<%= submit_tag '検索', data: { disable_with: '送信中'} %> ※作品名がヒットしない場合、英語入力も試して見てください!!
<% end %>
<% if @arrays.present? %>
<% @arrays.each do |array| %>
<br>
<div><%= array["title"] %></div>
<br>
<div><%= image_tag 'https://image.tmdb.org/t/p/w500'+array["poster_path %></div>
<br>
<div><%= array["overview"] %></div>
<br>
<div><%= array["release_date"] %></div>
<% if @vods.present? %>
<p><%= @vod1 %></p>
<% if @vod2.present? %>
<p><%= @vod2 %></p>
<% end %>
<% if @vod3.present? %>
<p><%= @vod3 %></p>
<% end %>
<% if @vod4.present? %>
<p><%= @vod4 %></p>
<% end %>
<% else %>
<p>配信しているvodはありません!!</p>
<% end %>
<% end %>
2018/10/24 14:37
aaa = @array.@vod1 こんな感じでまとめるという意味でしょうか?
2018/10/24 14:42
2018/10/24 16:53 編集
@arrays = hash["results"]これと、
vod1 = -div[1]-
vod2 =--div[1]-
vod3 =--div[1]-
vod4 =--div[1]-
vods = [vod1,vod2,vod3,vod4]
これを繋げて、まとめて出力すればいいということですよね?
2018/10/24 16:57
n = num + 1
div[n]みたいにして足していきたいです
2018/10/24 16:59
view側でarray['vod']といった感じで出力できるようになります。
もしくは@arraysと同じ順番のvod用配列を用意すれば
(0...@arrays.length).each { |i|
# @arrays[i]["title"]
# @vod_array[i]
}
で出力できるようになります。
2018/10/24 17:01
2018/10/24 17:07
@vod1はseleniumのスクレイピングで取得したものになります。
ありがとうございます!
一度やってみます