Ruby // Nokogiri 尝试将各种对象的选择器存储在哈希中
Ruby // Nokogiri trying to store selectors for various objects in a hash
我正在尝试将选择器存储在分配给适当主题的哈希中,然后我将从网页上抓取这些主题。但是,当我这样做时,我遇到了“css”方法的 'undefined method' 错误。
示例:
@@letters_hash = {
"a" => {
uppercase: "A",
history: css('div.class_1').css('div.class_2').text,
url: "www.alphabet.com"
}
}
有没有办法封装这个?或者,如果我将它存储为字符串,是否有办法删除该字符串并将其返回给方法?
感谢您的宝贵时间。
css('div.class_1').css('div.class_2').text
是 self.css('div.class_1').css('div.class_2').text
,self
是你的 Database
class。它没有 css 方法。您需要在具有 css 方法的对象上调用该方法,例如 Nokogiri 节点。
回调
如果你想存储一组方法来调用你稍后会得到的一些 Nokogiri 节点,你可以 a callback using a little anonymous function called a lambda.
@letters = {
"a" => {
uppercase: "A",
history: ->(node) { node.css('div.class_1').css('div.class_2').text },
url: "www.alphabet.com"
}
}
将节点作为参数并调用节点上的方法。
然后当你有一个节点时你可以调用这个函数。
@letters_hash[letter][:history].call(node)
对象
此时它已被编译,应该封装在一个对象中。
class LetterTopic
def initialize(letter)
@letter = letter
end
def node_history(node)
node.css('div.class_1').css('div.class_2').text
end
def uppercase
@letter.upcase
end
def url
"www.alphabet.com"
end
end
letters = {
"a" => LetterTopic.new("a")
}
node = ...get a Nokogiri node...
letters[letter].node_history(node)
关于 Class 变量的注意事项
@@letters_hash
并没有按照你的想法去做。 Class Ruby 中的变量由子class 共享。如果您子 class 数据库,它们将共享一个 @@letters_hash
变量。
class Database
@@letters = {}
def self.letters
@@letters
end
end
class Databasement < Database
end
Database.letters[:a] = 'database'
Databasement.letters[:a] = 'databasement'
p Database.letters # {:a=>"databasement"}
p Databasement.letters # {:a=>"databasement"}
而是使用 Class 实例变量。与 Ruby 中的其他所有内容一样,数据库 class 是一个对象,可以拥有自己的实例变量。
class Database
# Everything inside `class << self` works on the class object.
class << self
def letters
@letters ||= {}
end
end
end
class Databasement < Database
end
Database.letters[:a] = 'database'
Databasement.letters[:a] = 'databasement'
p Database.letters # {:a=>"database"}
p Databasement.letters # {:a=>"databasement"}
我正在尝试将选择器存储在分配给适当主题的哈希中,然后我将从网页上抓取这些主题。但是,当我这样做时,我遇到了“css”方法的 'undefined method' 错误。
示例:
@@letters_hash = {
"a" => {
uppercase: "A",
history: css('div.class_1').css('div.class_2').text,
url: "www.alphabet.com"
}
}
有没有办法封装这个?或者,如果我将它存储为字符串,是否有办法删除该字符串并将其返回给方法?
感谢您的宝贵时间。
css('div.class_1').css('div.class_2').text
是 self.css('div.class_1').css('div.class_2').text
,self
是你的 Database
class。它没有 css 方法。您需要在具有 css 方法的对象上调用该方法,例如 Nokogiri 节点。
回调
如果你想存储一组方法来调用你稍后会得到的一些 Nokogiri 节点,你可以 a callback using a little anonymous function called a lambda.
@letters = {
"a" => {
uppercase: "A",
history: ->(node) { node.css('div.class_1').css('div.class_2').text },
url: "www.alphabet.com"
}
}
将节点作为参数并调用节点上的方法。
然后当你有一个节点时你可以调用这个函数。
@letters_hash[letter][:history].call(node)
对象
此时它已被编译,应该封装在一个对象中。
class LetterTopic
def initialize(letter)
@letter = letter
end
def node_history(node)
node.css('div.class_1').css('div.class_2').text
end
def uppercase
@letter.upcase
end
def url
"www.alphabet.com"
end
end
letters = {
"a" => LetterTopic.new("a")
}
node = ...get a Nokogiri node...
letters[letter].node_history(node)
关于 Class 变量的注意事项
@@letters_hash
并没有按照你的想法去做。 Class Ruby 中的变量由子class 共享。如果您子 class 数据库,它们将共享一个 @@letters_hash
变量。
class Database
@@letters = {}
def self.letters
@@letters
end
end
class Databasement < Database
end
Database.letters[:a] = 'database'
Databasement.letters[:a] = 'databasement'
p Database.letters # {:a=>"databasement"}
p Databasement.letters # {:a=>"databasement"}
而是使用 Class 实例变量。与 Ruby 中的其他所有内容一样,数据库 class 是一个对象,可以拥有自己的实例变量。
class Database
# Everything inside `class << self` works on the class object.
class << self
def letters
@letters ||= {}
end
end
end
class Databasement < Database
end
Database.letters[:a] = 'database'
Databasement.letters[:a] = 'databasement'
p Database.letters # {:a=>"database"}
p Databasement.letters # {:a=>"databasement"}