我正在尝试用Ruby学习脚本,这是我的第一个问题。
我有一个包含州及其城市的HTML文件。我需要能够在我的Ruby代码中访问城市并知道它们属于哪个州,所以我计划解析HTML并为每个城市创建一个哈希,如下所示:{New York =>纽约市}。
我正在尝试使用Nokogiri,我现在才开始学习。
<h4>State</h4>
<ul>
<li>city</li>
<li>city</li>
<li>city</li>
</ul>
<h4>State</h4>
<ul>
<li>city</li>
<li>city</li>
<li>city</li>
</ul>
<h4>State</h4>
<ul>
<li>city</li>
<li>city</li>
<li>city</li>
</ul>
我正在使用它将状态变为数组:
require 'rubygems'
require 'nokogiri'
page = Nokogiri::HTML(open("to_parse.html"))
states = Array.new(100), index = 0
page.css('h4').each do |s|
states[index] = s.text
puts states[index]
index += 1
end
这实际上并没有真正帮助;我需要弄清楚如何让Nokogiri
将每个列表的元素解析为包含城市及其状态的hashes
。我不确定如何在完成一个州的城市列表时有一个循环中断,并为下一个州的城市列表创建一组新的hashes
。
我想我必须为每个列表元素创建一个hash
,并在每个h4
内存储该列表的hash
标记文本,所以我知道哪个这个城市属于。这就是我不确定该怎么做。
随意提供一些关于重构我所得到的建议,因为我知道它可以做得更好。
答案 0 :(得分:1)
XPath选择器可以帮助你。
states = doc.css('li').map do |city|
state = city.xpath('../preceding-sibling::h4[1]')
[city.text, state.text]
end.to_h
#=> {'city' => 'State', ...}
这会抓取所有li
城市元素,然后追溯到他们的状态。 (XPath如下所示:..
=向上一级,preceding-sibling::h4
=前面的h4
元素,[1]
=第一个这样的元素)
对您的代码的一些评论:在Ruby中,您不需要初始化数组,并且使用像map
这样的Enumerable方法,您永远不需要在循环中跟踪索引变量。
请注意,最终的to_h
仅适用于Ruby 2.1或更高版本。