2017-04-06 12 views
1

CLIアプリケーションでエラーが発生するメソッドがあります。定義されていないメソッド `attr 'for nil:NilClass(NoMethodError)

def self.deal_page(input, product_url) 
    self.open_deal_page(input) 
    deal = {} 
    html = open(@product_url) 
    doc = Nokogiri::HTML(html) 
    data = doc.text.strip 
    deal[:name] = doc.css("h1").text.strip 
    deal[:discription] = doc.css(".textDescription").text.strip 
    @purchase_link = nil 
    @purchase_link= doc.at_css("div.detailLeftColumn a.success").attr("href") 
     if @purchase_link.nil? 
     deal[:purchase] = @product_url 
     else 
     deal[:purchase] = @purchase_link 
     end 
    deal 
    end 

とエラーがある:

方法がある

/home/himachhag-45739/code/popular-deals-from-slickdeals.net-cli/lib/popular_deals/newdeals.rb:54:in `deal_page': undefined method `attr' for nil:NilClass (NoMethodError) 
     from /home/himachhag-45739/code/popular-deals-from-slickdeals.net-cli/lib/popular_deals/cli.rb:70:in `disply_deal'             
     from /home/himachhag-45739/code/popular-deals-from-slickdeals.net-cli/lib/popular_deals/cli.rb:49:in `menu'               
     from /home/himachhag-45739/code/popular-deals-from-slickdeals.net-cli/lib/popular_deals/cli.rb:9:in `call'               
     from /home/himachhag-45739/code/popular-deals-from-slickdeals.net-cli/bin/popular-deals:10:in `<top (required)>'             
     from /usr/local/rvm/gems/ruby-2.3.1/bin/popular-deals:22:in `load'                         
     from /usr/local/rvm/gems/ruby-2.3.1/bin/popular-deals:22:in `<main>'                        
     from /usr/local/rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `eval'                       
     from /usr/local/rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `<main>' 

私はxpathat_cssunlessif ... elseを試してみましたが、助けにはなりません。また、私は毎回このエラーを取得しませんが、私はそれを取り除きたいです。あなたのスタックトレースとして

+1

このような問題に直面しているときは、1つの操作をやめて何ができなかったかを確認することが重要です。 'doc.at_css(...)'が何も見つからなかったようです。もう一つ注目すべき点は、インデントの一貫性を維持しようとすることです。その 'if'節がそこに押し込まれてしまったようです。 – tadman

+0

@tadmanご意見ありがとうございました。私はあなたに同意します。doc.at_css(...)が何も見つけられなかったようです。しかし、同じ取引を探すためにもう一度試してみると、それは私に出力を与えます!私は理解していません。私はインデントについてももっと注意するでしょう。 –

+0

ようこそ。 「[mcve]」とリンク先のページをお読みください。問題を確認できるコードを提供する必要があります。現在、あなたのメソッドを呼び出す方法を教えてくれなかったので、現在はできません。 –

答えて

4

一つの方法は、偏執的なビットになることです。 Ruby nilfalseは論理的に偽ですので、具体的にnil?をテストする必要はほとんどありません。必要なのは、nilfalseを区別したい場合です。これはあまり頻繁ではないと思います。

この場合、at_cssで何かを押すか、そうしなかった場合、tryコールは何もしません。何かを見つけたらtryコールはもう1回コールを行います。次に、単純な||(または)演算子を使用して代入を行い、優先順位でそれらを選択することができます。

もう1つのことは、このコードはクラスメソッドの中にあり、インスタンス変数を使用することは面倒です。 purchase_linkのようなものがこのメソッド内でのみ使用される場合は、永続化する@を削除してください。

では注意すべきもう一つは、あなたの方法は次のように定義された方法:内部

def self.deal_page(input, product_url) 
引数 product_urlを宣言

、しかし:これは@product_url変数クラスのインスタンスを参照

html = open(@product_url) 

同じではありません。ここで間違った変数を使用してopenと呼んでいる可能性があります。

def self.deal_page(input, product_url) 
    ... 
    html = open(@product_url) 

あなたは、パラメータとしてproduct_urlを使用しますが、@product_urlをオープンしようとしている:私は問題だと思うのはここ

+2

'.try()'は[Ruby](https://apidock.com/rails/v3.2.1/Object/try)メソッドであり、Rubyのコアメソッドではありません。 [安全なナビゲーション演算子](http://stackoverflow.com/questions/36812647/what-does-ampersand-dot-mean-in-ruby)は 'doc.at_css()&。attr()のRubyと同等です。 '。 – anothermh

+0

2.3では安全なナビゲーション演算子が導入されました。これは実際には 'try'よりはるかに一貫しています。私はRails特有のことを忘れていました。 – tadman

+1

@tadmanこのソリューションは機能します!私はあなたの時間と提案を本当に感謝しています。 –

0

は、この行がエラーの原因となっている示しています

@purchase_link= doc.at_css("div.detailLeftColumn a.success").attr("href") 

attr方法は皆無で呼び出すことはできません。要素がHTMLに存在するかどうかを確認します。

あなたがhttp://www.nokogiri.org/tutorials/を参照することができます詳細については

doc.at_css("div.detailLeftColumn a.success") 

の値を印刷して、これをデバッグすることができます。物事のカップルがここに心に留めておくために

@purchase_link = doc.at_css("div.detailLeftColumn a.success").try(:attr, "href") 

deal[:purchase] = @purchase_link || @product_url 

:この問題に対処する

0

です。 @product_urlが空かnilであるので、@product_urlどこかが、明らかではない、この方法で事前に定義されなければならない場合

openは、エラーが発生します。私はあなたが思っているページではないと思っています。その結果、セレクタが失敗します。

あなたはあなたのコード内の他の問題を抱えて:あなたはその後、ほとんど常にあるノードセット内のすべてのテキストを、連結textをノードセット

doc.css('h1').class # => Nokogiri::XML::NodeSet 

を返しcssを、使用している

deal[:name] = doc.css("h1").text.strip 
deal[:discription] = doc.css(".textDescription").text.strip 

はありません。あなたがしたいこと。このことを考えてみましょう:

require 'nokogiri' 

doc = Nokogiri::HTML(DATA.read) 
doc.css('h1').text # => "foobar" 
doc.css('h1').map(&:text) # => ["foo", "bar"] 

__END__ 
<html> 
    <body> 
    <h1>foo</h1> 
    <h2>blah</h2> 
    <h1>bar</h1> 
    <h2>blah</h2> 
    </body> 
</html> 

doc.css('h1').text連結"foo""bar""foobar"になります。それが起こったら、連結によって引き起こされる混乱を解くことは非常に困難です。

doc.css('h1').map(&:text)の代わりにrareという文字を実際に連結する必要がある場合を除いて、使用する必要があります。私はそのような状況に遭遇しました...ああ...決して時間はありません。

関連する問題