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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

1334閲覧

discordbot製作中の「NoMethodError」

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2018/08/31 13:15

編集2018/08/31 16:32
最近discordbotなどの存在を知り、rubyを使い始めた初心者です。 今回、WOTというゲームのトーナメントのページが更新されたらdiscordのテキストチャンネルに通知するというプログラムが組みたくていろいろ調べながらやっていました。 コマンドプロンプトで > ruby discordbot.rb と入力してbotを起動させようとしたところ discordbot.rb:23:in `block in <main>': undefined method `css' for nil:NilClass (NoMethodError) from discordbot.rb:15:in `loop' from discordbot.rb:15:in `<main>' というエラーが出てきました。調べてもよくわからず進展がない状態です。 組んだプログラムは # encoding: utf-8 require 'discordrb' require 'open-uri' require 'nokogiri' require 'certified' bot = Discordrb::Commands::CommandBot.new token: 'NDY4NDIzMjE5MzE4MjI2OTQ0.Di48uA.OEDvrwbK5Yrm_M8o1URofoFgUxY', prefix: '!' bot.message(with_text: 'Ping!') do |event| event.respond 'Pong!' end bot.run :async loop do # 1時間ごとにアナウンスページを確認して、差分があれば内容を通知 # HTML解析 doc = Nokogiri::HTML.parse(open('https://worldoftanks.asia/ja/tournaments/')) # 一番新しいトピックタイトルを取得 node = doc.xpath('//div[@class="news_content no_img"]') now_topic = node[0].css('strong').inner_text # 前回取得したトピックから更新があれば通知 if now_topic != File.read('data/sitecheck/current.txt') then # brタグを"\n"に変換 doc.search('br').each do |br| br.replace("\n") end msg = <<-EOS トーナメントページが更新されました 「#{now_topic}」 doc.at_xpath("//div[@class = 'i_contents']").content https://worldoftanks.asia/ja/tournaments/ EOS bot.send_message([418316166621298688], msg) # 今回取得したトピックを保存 File.open("data/sitecheck/current.txt", "w") do |f| f.print("#{now_topic}") end DEND sleep(3600) DEND DEND end end bot.run です。 最近プログラミングを始めたものなので解説記事からコピペしたものがほとんどで意味が分かっていないものもあります。 どなたかわかる方がいましたらどこをどう言う風に変えたら直るのか教えてください。

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

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

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

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

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

guest

回答2

0

本題とは関係ないのですが,質問文の作成の仕方についてひとこと

PCで見てもらうと分かりやすいのですが,
質問文の編集画面は左側が入力,右側が出力になっています.
入力はmarkdawn形式で行い,右側のプレビューで回答者からの見た目を確認できます

markdawnでは,「#」は見出しを表す文字であるため,コメントを示す「#」が見出しとして表示されてしまいます.なので,ソースコード部分は以下のようにcodeブロックで囲ってください
イメージ説明

インデントが保持されるだけでなく,シンタックスハイライトが付き可読性が高まります.
また,コピペもしやすくなります

投稿2018/08/31 15:20

liveasnotes

総合スコア1284

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

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

0

ベストアンサー

undefined method 'css' for nil:NilClass (NoMethodError)

これは、cssというメソッドがNilClassに定義されていないよ〜!というエラーです。
今後Rubyで遊んでいくと、よく見かけることになるエラーだと思います。

該当のコードはこのあたりでしょうか。

ruby

1node = doc.xpath('//div[@class="news_content no_img"]') 2now_topic = node[0].css('strong').inner_text

node[0]nilになっているようですね。
class="news_content no_img"を持つdivが見つからないせいでしょうか。

少しDOM検索の条件が厳しいように感じましたので、
代わりに以下のようなコードに差し替えるのがよいかな?と思いました。

ruby

1doc.at_css('div.news_content.no_img > strong').inner_text

at_cssはCSSのクエリを使って検索し、見つかった要素のひとつ目をひとつ返す、というメソッドです。

Nokogiriを使用したクローラーめも (Kenya さん、良い記事をありがとうございます)

しかし、 ot_amay さんが貼られたリンク先に、そのようなDOMを見つけることができませんでした。。
ot_amay さんが求められているものか分かりませんが、以下のコードでそれっぽい文字列を取得することができると思います。

ruby

1now_topic = doc.at_css('.landing-list .landing-list_item .landing-list_name').inner_text

実際に実行していないため、動くかどうかわかりません。動かなかったらごめんなさい!

投稿2018/08/31 14:53

編集2018/08/31 22:42
rigani_c

総合スコア69

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

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

退会済みユーザー

退会済みユーザー

2018/08/31 16:15 編集

# encoding: utf-8 require 'discordrb' require 'open-uri' require 'nokogiri' require 'certified' bot = Discordrb::Commands::CommandBot.new token: 'NDY4NDIzMjE5MzE4MjI2OTQ0.Di48uA.OEDvrwbK5Yrm_M8o1URofoFgUxY', prefix: '!' bot.message(with_text: 'Ping!') do |event| event.respond 'Pong!' end bot.run :async loop do # 1時間ごとにアナウンスページを確認して、差分があれば内容を通知 # HTML解析 doc = Nokogiri::HTML.parse(open('https://worldoftanks.asia/ja/tournaments/')) # 一番新しいトピックタイトルを取得 node = doc.xpath'#div[@doc.at_css(div)'divnews_content end end end end end end end end no_img > strong[]inner_text end end]end now_topic = node[0].css('strong').inner_text node_topic = doc.at_css('.landing-list .landing-list_item .landing-list_name').inner_text # 前回取得したトピックから更新があれば通知 if now_topic != File.read('data/sitecheck/current.txt') then # brタグを"\n"に変換 doc.search('br').each do |br| br.replace("\n") end msg = <<-EOS トーナメントページが更新されました 「#{now_topic}」 doc.at_xpath("//div[@class = 'i_contents']").content https://worldoftanks.asia/ja/tournaments/ EOS bot.send_message([418316166621298688], msg) # 今回取得したトピックを保存 File.open("data/sitecheck/current.txt", "w") do |f| f.print("#{now_topic}") end DEND sleep(3600) DEND DEND end end-of-input bot.run コードを差し替えたり追加したりしつつsyntax errorにも対応しながら修正を加えていったところ discordbot.rb:22: syntax error, unexpected tIDENTIFIER, expecting keyword_end ...doc.at_css(div)'divnews_content end end end end end end end ... ...       ^ というエラーが永遠とで続けるようになりました。22行目にendが大量にあるのはそのためです。修正の仕方が間違っているのでしょうか。それともこんなにも連続してendを書くプログラムがあるのでしょうか。 投稿するとなぜかエラーメッセージの矢印の位置がずれますね。本来はcontentとendの間にあります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問