我经常发现自己正在处理这种情况:
require 'nokogiri'
require "open-uri"
url = "https://www.random_website.com/contains_info_I_want_to_parse"
nokodoc = Nokogiri::HTML(open(url))
# Let's say one of the following line breaks the ruby script
# because the element I'm searching doesn't contain an attribute.
a = nokodoc.search('#element-1').attribute('href').text
b = nokodoc.search('#element-2').attribute('href').text.gsub("a", "A")
c = nokodoc.search('#element-3 h1').attribute('style').text.strip
我将创建大约30个变量,所有这些变量都在页面中搜索不同的元素,我将在多个页面上循环该代码。但是,这些页面中的一些可能具有如此略微不同的布局,并且不会具有这些div中的一个。这将破坏我的代码(因为你不能在nil上调用.attribute或.gsub)。但我永远无法猜到前一条线。 我的解决方案通常是围绕每一行:
begin
line #n
rescue
puts "line #n caused an error"
end
我希望能够做到这样的事情:
url = "https://www.random_website.com/contains_info_I_want_to_parse"
nokodoc = Nokogiri::HTML(open(url))
catch_error(a, nokodoc.search('#element-1').attribute('href').text)
catch_error(b, nokodoc.search('#element-2').attribute('href').text.gsub("a", "A"))
catch_error(c, nokodoc.search('#element-3 h1').attribute('style').text.strip)
def catch_error(variable_name, code)
begin
variable_name = code
rescue
puts "Code in #{variable_name} caused an error"
end
variable_name
end
我知道放&在每种新方法运作之前:
nokodoc.search('#element-1')&.attribute('href')&.text
但我希望能够在终端中显示错误并使用'puts'来查看我的代码何时出错。
有可能吗?
答案 0 :(得分:1)
您不能将code
作为常规参数传递给方法,因为它会在传递给catch_error
方法之前进行评估(并引发异常)。您可以将其作为块传递 - 类似于
a = catch_error('element_1 href text') do
nokodoc.search('#element-1').attribute('href').text
end
def catch_error(error_description)
yield
rescue
puts "#{error_description} caused an error"
end
请注意,您无法将a
作为variable_name
传递给该方法:在调用该方法之前,它尚未在任何地方定义,因此您将获得{\ n} { {1}}错误。即使您之前定义undefined local variable or method
,它也无法正常工作。如果您的代码在不引发异常的情况下工作,则该方法将返回正确的值,但该值不会存储在方法范围之外的任何位置。如果存在异常,a
将在方法之前具有variable_name
之前的任何值(a
,如果您在未设置的情况下定义它),那么您的错误消息将输出类似{{1}的内容}}。这就是我添加nil
参数的原因。
如果您不想每次都指定错误说明,也可以尝试记录邮件和回溯。
Code in caused an error
我在这里做了一个额外的更改:将文档作为参数传递,以便error_description
可以轻松记录标识文档的内容,以防重要。