【问题标题】:Why is my rails if / else getting a NoMethodError为什么我的 rails if / else 得到 NoMethodError
【发布时间】:2013-12-03 23:30:12
【问题描述】:

我正在使用 Mechanize 从 KBB.com 上抓取数据,我的应用获取一个 url,然后使用 Mechanize 浏览各个页面并找到给定 url 的价格。一个 url 可以指向许多不同的页面,我的应用程序需要能够确定它到达了哪个页面。我目前正在使用 if / else 语句来指导逻辑,但我遇到了一个我似乎无法调试的问题。

当我的应用到达 if / else 语句并检查条件时:

if agent.page.link_with(:text => "Choose this style")

我明白了:

NoMethodError (undefined method `link_with' for nil:NilClass)

我尝试使用以下方法进行调试:

 debugger if agent.page.link_with(:text => "Choose this style").nil?

但这给了我与上面相同的错误,只是这一次它说调试器代码是问题的根源。

我该如何调试呢?或者有什么更好的编码方式,这样我的应用就不会遇到这个异常?

代码如下:

def kbb_value(url)
agent = Mechanize.new

# rescue bad urls
begin
  page = agent.get(url)
rescue Mechanize::ResponseCodeError
  begin
    agent.cookie_jar.clear!
    page = agent.get(url.sub('styles', 'categories'))
  rescue Mechanize::ResponseCodeError
    page = 'http://www.kbb.com/acura/rsx/2002-acura-rsx/styles/?intent=buy-used'
  end
end  


# kbb.com has cookie problems - solution is to clear cookies after every request

agent.cookie_jar.clear!

# program determines which starting page it is on via if / else
debugger if agent.page.link_with(:text => "Choose this style").nil?
if agent.page.link_with(:text => "Choose this style")
  agent.page.link_with(:text => "Choose this style").click

  # if the page allows additional options - skip that page 

  if agent.page.link_with(:text => "Choose price type")
    agent.cookie_jar.clear!
    agent.page.link_with(:text => "Choose price type").click
  end  

elsif agent.page.link_with(:text => "Choose price type")
  agent.page.link_with(:text => "Choose price type").click
else
  agent.page.link_with(:href => /bodystyle/).click
  agent.cookie_jar.clear!
  agent.page.link_with(:text => 'Choose this style').click
  agent.cookie_jar.clear!
  agent.page.link_with(:text => "Choose price type").click
end   

 # Get the 'Good' car price from kbb.com

agent.cookie_jar.clear!
agent.page.links_with(:text => "Get used car price")[2].click

# instead of getting the 'retail' value, substitute in 'private-party' in the url. Then get that page and grab the kbb value.

agent.cookie_jar.clear!
agent.get(agent.page.uri.to_s.sub('retail', 'private-party'))
@kbb_value = agent.page.at('.selected .value').text.delete('$')
end  

【问题讨论】:

  • 什么是agent.page?或者,更准确地说,你为什么将 page 设置为一个值然后从不使用它?

标签: ruby-on-rails debugging mechanize nomethoderror


【解决方案1】:

试试看:

agent.page.link_with(:text => "Choose this style") rescue debugger

页面好像是nil

【讨论】:

  • 这与删除所有对变量“页面”的引用一起解决了我的问题。不过我的调试器从来没有出现过..奇怪。
【解决方案2】:

看起来可能是以下两种情况之一:

  • 我从未使用过 mechanize,但您将结果分配给名为 page 的变量,而不是 agent.page。尝试更改它以与page.links_with 进行比较,而不是agent.page.links_with,后者可能为空。

  • Ruby 具有块变量作用域,在块内定义的任何变量都不会存在于块之外。您在开始内分配您的页面(我相信这是一个块范围)。尝试更改它,以便将页面 outside 定义为范围(为 nil),然后只需在 begin/rescue 内分配值。

代码修复示例:

# Assign the page variable outside of the scope
page = nil
begin
  page = agent.get(url)
rescue Mechanize::ResponseCodeError
  begin
    agent.cookie_jar.clear!
    page = agent.get(url.sub('styles', 'categories'))
  rescue Mechanize::ResponseCodeError
    page = 'http://www.kbb.com/acura/rsx/2002-acura-rsx/styles/?intent=buy-used'
  end
end

# Check the "page" variable
debugger if page.link_with(:text => "Choose this style").nil?

注意:我已经有一段时间没有使用 Ruby 了,并且永远没有使用 Mechanize。试一试,希望他们有所帮助。

【讨论】:

  • 非常可靠的答案。谢谢!我不知道块范围。
【解决方案3】:

您收到此错误是因为 Mechanize 未加载页面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 2016-02-16
    相关资源
    最近更新 更多