2017-04-06 5 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>' 

내가 xpath, at_css, unless, if .. else을 시도했지만 도움이되지 않습니다. 또한 매번이 오류가 발생하지는 않지만 제거하고 싶습니다. 당신의 스택 트레이스로

+1

이와 같은 'nil' 문제에 직면 할 때 한 번의 작업을 취소하고 어떤 작업을 수행하지 못했는지 확인하는 것이 중요합니다. 'doc.at_css (...)'가 아무것도 찾지 못했던 것 같습니다. 또 다른주의 할 점은 들여 쓰기를 일관되게 유지하는 것입니다. 그'if' 절이 제자리에 빠진 것처럼 거기에 눌려 있습니다. – tadman

+0

@ tadman 귀하의 제안에 진심으로 감사드립니다. 나는 doc.at_css (...)가 아무것도 찾지 못했음을 당신에게 동의합니다. 하지만 다시 같은 거래를 찾으면 나에게 결과물을줍니다! 나는 이해하지 못한다. 들여 쓰기에 대해서도 더주의해야합니다. –

+0

SO에 오신 것을 환영합니다. "[mcve]"와 링크 된 페이지를 읽으십시오. 문제를 확인할 수있는 코드를 제공해야합니다. 현재 우리는 방법을 호출하는 방법을 알려주지 않았기 때문에이를 수행 할 수 없습니다. –

답변

4

한 가지 방법은 편집증 조금이 될 것입니다. Ruby 에만nilfalse은 논리적으로 거짓이므로 사물에 특별히 nil?을 테스트 할 필요는 매우 드뭅니다. 필요한 유일한 경우는 nilfalse을 구별하기를 원할 때입니다. 자주 상상할 수있는 것은 아닙니다.

이 경우 at_css으로 무엇인가를 누르거나 그렇지 않은 경우 try 호출이 아무 것도하지 않습니다. 뭔가 찾으면 try 통화가 한 번 더 통화를합니다. 그런 다음 간단한 || (또는) 연산자를 사용하여 우선 순위를 지정하여 할당 할 수 있습니다.

이 코드는 클래스 메서드 내부에 있기 때문에 자연스럽게 인스턴스 변수를 사용하면 문제가 발생할 수 있습니다. 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 메소드가 아니라 [Rails] (https://apidock.com/rails/v3.2.1/Object/try) 메소드입니다. [안전한 탐색 연산자] (http://stackoverflow.com/questions/36812647/what-does-ampersand-dot-mean-in-ruby)는'doc.at_css() &. attr() '에 해당하는 Ruby와 같습니다. '. – anothermh

+0

2.3은 안전한 탐색 연산자를 도입했는데 실제로는 '시도'보다 훨씬 일관성이 있습니다. 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가 비어 있거나 전무 경우

open에서 오류가 발생, 그래서 @product_url 어딘가에을 미리 정의해야하지만. 나는 이것이 당신이 생각하는 페이지가 아닌 것으로 의심하고, 그 결과 선택자가 실패합니다. 노드 집합 거의 항상있는 노드 세트에서 모든 텍스트를 연결합니다

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

text을 반환, 당신은 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)을 사용해야합니다. 나는 그 상황에 처했을 뿐이 오 ... 절대로.

관련 문제