删除/忽略不需要的文本是不是一个引入nokogiri问题,这是一个字符串处理的问题:
require 'nokogiri'
doc = Nokogiri::HTML(<
li class="object-props-item price"
CHF 14'900.-
61'000 kmEOT
str = doc.at('strong').text # => "CHF 14'900.-"
此时str包含节点的文本。
一个简单的正则表达式将提取,这是为了获取数据的直接方式:
str[/[\d']+/] # => "14'900"
sub可以用来除去'CHF '子:
str.sub('CHF ', '') # => "14'900.-"
delete可用于除去字符C,H,F和:
str.delete('CHF ') # => "14'900.-"
tr可以用来去除一切不是0 .. 9,',.或-:
str.tr("^0-9'.-", '') # => "14'900.-"
修改上面的一个,如果你不想',.或-做。
为什么的里程不显示
的数据,因为你的CSS选择器和实际class参数之间的不匹配:
require 'nokogiri'
doc = Nokogiri::HTML('
61'000 km')doc.at('.mileage').text # =>
# ~> NoMethodError
# ~> undefined method `text' for nil:NilClass
# ~>
# ~> /var/folders/yb/whn8dwns6rl92jswry5cz87dsgk2n1/T/seeing_is_believing_temp_dir20160428-96035-1dajnql/program.rb:5:in `'
相反,它应该是:
doc.css('.milage').text # => "61'000 km"
但这并不全是错的。有一个微妙的问题等待你咬你。
css或search返回一个节点集而at或at_css返回一个元素:
doc.css('.milage').class # => Nokogiri::XML::NodeSet
doc.at('.milage').class # => Nokogiri::XML::Element
下面是当text传递包含多个匹配的节点一个节点集会发生什么:
doc = Nokogiri::HTML('
foo
bar
')doc.search('p').class # => Nokogiri::XML::NodeSet
doc.search('p').text # => "foobar"
doc.at('p').class # => Nokogiri::XML::Element
doc.at('p').text # => "foo"
当使用text使用NodeSet,它将所有节点的文本连接成单个字符串。这可能会使文本从一个节点与另一个节点分离变得非常困难。相反,使用at或其中一个at_*等价物可从单个节点获取文本。如果你想单独提取每个节点的文本,并得到一个阵列中使用:
doc.search('p').map(&:text) # => ["foo", "bar"]
最后,注意你的HTML示例是无效的:
doc = Nokogiri::HTML(<
li class="object-props-item price"
CHF 14'900.-
61'000 km')EOT
puts doc.to_html
# >>
# >>
# >>
li class="object-props-item price"
# >> CHF 14'900.-
# >>
# >>
61'000 km')# >>
这里发生了什么:
doc = Nokogiri::HTML(<
li class="object-props-item price"
CHF 14'900.-
61'000 km')EOT
doc.at('.price') # => nil
引入nokogiri已经做了修复行动,使第一线的感觉,所以它包装在
。通过这样做,.price类不再存在,因此您的代码将再次失败。
固定的标签结果的正确响应:
doc = Nokogiri::HTML(<
CHF 14'900.-
61'000 km')EOT
doc.at('.price').to_html # => "
\n CHF 14'900.-\n"这就是为什么它,以确保您的输入有效真的很重要。没有它,试图复制你的问题是困难的。