Html 用Xpath解析

Html 用Xpath解析,html,ruby,xpath,nokogiri,Html,Ruby,Xpath,Nokogiri,考虑以下HTML: <div class='data'> <div class='user_name'>Lankesh</div> <div class='user_details'> <div class='country'>Srilanka</div> <div class='age'>9</div> </div> <div class='user

考虑以下HTML:

<div class='data'>
  <div class='user_name'>Lankesh</div>
  <div class='user_details'>
    <div class='country'>Srilanka</div>
    <div class='age'>9</div>
  </div>
  <div class='user_name'>Bob</div>
  <div class='user_details'>
    <div class='country'>US</div>
    <div class='age'>54</div>
  </div>
  <div class='user_name'>Deiter</div>
  <div class='user_details'>
    <div class='country'>Germany</div>
    <div class='age'>34</div>
  </div>
  <div class='user_name'>Yakob</div>
  <div class='user_details'>
    <div class='country'>Syria</div>
    <div class='age'>90</div>
  </div>
  <div class='user_name'>Qureshi</div>
  <div class='user_details'>
    <div class='country'>Afgan</div>
    <div class='age'>56</div>
  </div>
  <div class='user_name'>Smith George</div>
  <div class='user_details'>
    <div class='country'>India</div>
    <div class='age'>23</div>
  </div>
</div>
这可以用来提取数据,但我怎样才能分块(姓名、年龄和国家),以便更容易地将解析后的数据提取到结构中

  • 由于name在user\u details块之外,因此我无法编写如下查询:
    //div[@class='user\u details']
    并提取每个属性
  • 我知道我可以将数组分为3组;但我正在寻找基于xpath的解决方案,因为我的实际需要有不同数量的子属性
  • 愚蠢,但是:无论如何,在解析过程中,以某种方式将字符注入到提取的文本中

有什么想法吗?

首先让我说,最好调整HTML以将每个用户块包装在其自己的包含div中:

<div class='user'>
    <div class='name'>John</div>
    <div class='details'>
        <div class='country'>US</div>
        ...
    </div>
</div>

是的,您猜对了,我无法控制HTML。我懂拉链。但是有没有一种方法可以使用XPath来完成这项工作(也许我是在想象XPath的内容)我不这么认为,主要是因为XPath返回一个简单的结果列表,而且由于您的源代码没有分组,结果也不会分组。是否有任何理由希望它只在XPath中完成?您说这是因为user_details具有不同数量的属性,但我的解决方案在将其解析为数据结构时解决了这一问题,这正是您想要的:)?您是对的,但不知怎的,它实际上是如何解析的,这就是为什么我要进一步研究的原因。你的回答肯定是对的。但是,请看我发布的另一个问题;这就是我真正需要帮助的地方,我试图理解XPath。
<div class='user'>
    <div class='name'>John</div>
    <div class='details'>
        <div class='country'>US</div>
        ...
    </div>
</div>
require 'pp'
require 'nokogiri'

sample_html = File.open("r.htm", "r").read

n = Nokogiri::HTML::parse sample_html

user_names = n.xpath("//div[@class = 'user_name']")
user_details = n.xpath("//div[@class = 'user_details']")

users = user_names.zip(user_details).map do |name, details|
  {
    name: name.text,
    details: Hash[details.xpath("div").map { |d| [d['class'].to_sym, d.text] }]
  }
end

pp users

# [{:name=>"Lankesh", :details=>{:country=>"Srilanka", :age=>"9"}},
#  {:name=>"Bob", :details=>{:country=>"US", :age=>"54"}},
#  {:name=>"Deiter", :details=>{:country=>"Germany", :age=>"34"}},
#  {:name=>"Yakob", :details=>{:country=>"Syria", :age=>"90"}},
#  {:name=>"Qureshi", :details=>{:country=>"Afgan", :age=>"56"}},
#  {:name=>"Smith George", :details=>{:country=>"India", :age=>"23"}}]