如何在特定单词之后解析数据



我有一个HTML文档:

<div class="info">
  Country:
  <b>UK</b>
  <br>
  City:
  <b>London</b>
  <br>
  Name:
  <b>Jon</b>
  <br>
  Date:
  <b>12.08.2014</b>
  <br>
</div>

对于解析,我使用:

name = review_meta.search('.info b')[2].text
country = review_meta.search('.info b')[0].text
city = review_meta.search('.info b')[1].text
data = review_meta.search('.info b')[3].text

此代码不好,因为元素的顺序和数量可能会有所不同。

如何在特定单词之后解析数据?

上级:在Nokogiri中,我们可以使用JS选择器。但就我而言,无论如何只解析第一个元素。

require 'nokogiri'
html = <<_
<div class="info">
  Country:
  <b>UK</b>
  <br>
  City:
  <b>London</b>
  <br>
  Name:
  <b>Jon</b>
  <br>
  Date:
  <b>12.08.2014</b>
  <br>
</div>
_
doc = Nokogiri::HTML(html)
country = doc.at('.info:contains("Country:") b').text
city = doc.at('.info:contains("City:") b').text
name = doc.at('.info:contains("Name:") b').text
date = doc.at('.info:contains("Date:") b').text
puts country, city, name, date # => UK UK UK Uk

我该如何解决这个问题?

如何使用经典正则表达式解析它:

h = {}
str = review_meta.search('.info')[0].text
str.gsub(/[n]+/, '').split('<br>').reject { |item| item == '' }.each do |item|
  match = item.match(/([a-zA-Z]+):<b>([a-zA-Z0-9.]+)<.b>/)
  h[match[1].downcase.to_sym] = match[2]
end
p h
=> {:country=>"UK", :city=>"London", :name=>"Jon", :date=>"12.08.2014"}

。元素的顺序和数量可能会有所不同...

如果你不能指望文本的顺序或结构,那么你必须做一些事情来分解它,直到它可用。

如果我考虑得更久,我可能会写一些更有效的东西,但这就是我开始的地方:

require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<div class="info">
  Country:
  <b>UK</b>
  <br>
  City:
  <b>London</b>
  <br>
  Name:
  <b>Jon</b>
  <br>
  Date:
  <b>12.08.2014</b>
  <br>
</div>
EOT
hash = doc.at('.info').text # => "n  Country:n  UKn  n  City:n  Londonn  n  Name:n  Jonn  n  Date:n  12.08.2014n  n"
                      .strip # => "Country:n  UKn  n  City:n  Londonn  n  Name:n  Jonn  n  Date:n  12.08.2014"
                      .gsub(/n +/, "n") # => "Country:nUKnnCity:nLondonnnName:nJonnnDate:n12.08.2014"
                      .gsub(/:n/, ':') # => "Country:UKnnCity:LondonnnName:JonnnDate:12.08.2014"
                      .gsub(/nn/, ' ') # => "Country:UK City:London Name:Jon Date:12.08.2014"
                      .split  # => ["Country:UK", "City:London", "Name:Jon", "Date:12.08.2014"]
                      .map{ |s|
                        a, b = s.split(':')
                        [a.downcase, b]
                      } # => [["country", "UK"], ["city", "London"], ["name", "Jon"], ["date", "12.08.2014"]]
                      .to_h # => {"country"=>"UK", "city"=>"London", "name"=>"Jon", "date"=>"12.08.2014"}
hash['date'] # => "12.08.2014"

它将标签和值分解为一个哈希,此时您可以轻松获取单个值。

你可以用xpath来做,或者像这样:

doc.search('.info').children.find{|x| x.text['City:']}.next.text
#=> "London"
doc.search('.info').children.find{|x| x.text['Name:']}.next.text
#=> "Jon"

您想避免其他解决方案,使用正则表达式解析 HTML 是最后的手段。

相关内容

  • 没有找到相关文章

最新更新