2014-12-02 269 views
0

我正在使用Ruby,Mechanize和Nokogiri从网页上的iframe元素刮取源属性,并且如果存在多个元素,请将它们存储在数组中以供将来使用。将HTML元素添加到数组中

所以我有下面的代码工作,但我的问题是;有没有更好的方法来实现这个目标?说,沿着iframe.<some_method_like_length>而不是使用i计数器?

i = 0 
doc.search("//span/iframe").each do |iframe| 
    $ifrmsrc[i] = iframe.attribute("src") 
    i += 1 
end 
i = 0 
#LATER USE :) 
$ifrmsrc.length.times do |g| 
    puts $ifrmsrc.at(g) 
end 
+2

这个问题似乎是脱离主题,因为它是关于改善工作代码,属于[codereview.se]。 – 2014-12-02 17:57:57

回答

1

肯定。使用<<运算符将项添加到数组的末尾。

ifrmsrc = [] 

doc.search("//span/iframe").each do |iframe| 
    ifrmsrc << iframe.attribute("src") 
end 

...或者,更Rubyish,使用Enumerable#map,该单元执行每个项目的给定块中可枚举并返回结果的新阵列。

ifrmsrc = doc.search("//span/iframe").map {|iframe| iframe["src"] } 

(如果ifrmsrc已经存在,并且已经在它的数据要使用+=代替=因为=将覆盖它。不过,从你的代码我猜这是唯一的地方项目将添加到阵列中,因此不需要提前对其进行定义。)

PS Don't use global variables(即以$开头的变量)。这只是一个不好的做法。

+0

“这只是一个不好的做法。”这是代码味道;不要使用全局变量,除非它明白何时以及为什么要使用它们。 – 2014-12-02 17:59:17

+1

为简明起见,不使用iframe.attribute(“src”)使用iframe ['src']'。 – 2014-12-02 18:04:58

+0

@theTinMan好的提示;我已经更新了我的答案。 – 2014-12-02 18:05:32

0

我个人更喜欢更多的XPath:

ifrmsrc = doc.xpath("//span/iframe/@src").map(&:value) 

后来,你不需要索引迭代值:

ifrmsrc.each{ |src| puts src } 

或者,如果你需要其他指标理由:

ifrmsrc.each.with_index{ |src,i| puts "Source ##{i} is #{src}" } 

虽然,如果你只是想要的值,每一个林e:

puts ifrmsrc