Nokogiri xpath 中元素的迭代
Iterations of elements in Nokogiri xpath
我尝试对一些 <li>
元素进行迭代
迭代无法按预期工作:
require 'nokogiri'
doc = Nokogiri::HTML(<<-END_OF_HTML)
<ul class="attribute_radio_list">
<li>
<input type="radio" name="group_4" value="709" id="comb_709_group_4" checked="checked">
<label for="comb_709_group_4" class="label_comb_price label_comb_price_punda comb_709_group_4 checked">
<span class="radio_label">1-10 kg</span>
<span class="price_comb">14.85 €</span>
</label>
<span class="pundaline-variations-tooltip">1-10 kg</span>
</li>
<li class=" comb_710_group_4_li" id="comb_710_group_4_li">
<input type=" radio" name="group_4" value="710" id="comb_710_group_4">
<label for="comb_710_group_4">
<span class="radio_label">10-20 kg</span>
<span class="price_comb">17.82 €</span>
</label>
<span class="pundaline-variations-tooltip">10-20 kg</span>
</li>
<li id="comb_711_group_4_li">
<input type=" radio" name="group_4" value="711" id="comb_711_group_4">
<label for="comb_711_group_4">
<span class="radio_label">20-40 kg</span>
<span class="price_comb">19.80 €</span>
</label>
<span class="pundaline-variations-tooltip">20-40 kg</span></li>
</ul>
END_OF_HTML
lis = doc.xpath("//li")
lis.each do |li|
p li.xpath("//span[@class = 'price_comb']/text()").to_s
end
returns 这个:
"14.85 €17.82 €19.80 €"
"14.85 €17.82 €19.80 €"
"14.85 €17.82 €19.80 €"
但我应该看到这个:
"14.85 €"
"17.82 €"
"19.80 €"
为什么 xpath
工作起来很奇怪,我该如何解决?
您的 XPath 表达式开头缺少一个点 .
。
而不是
"//span[@class = 'price_comb']/text()"
应该是
".//span[@class = 'price_comb']/text()"
所以整个代码片段将是:
lis.each do |li|
p li.xpath(".//span[@class = 'price_comb']/text()").to_s
end
此 XPath 表达式 //span[@class = 'price_comb']/text()
是从文档的顶部开始搜索,而不是在特定节点内。
要使其在节点内搜索,您应该以点 .
开头表达式:.//span[@class = 'price_comb']/text()
更新
正如 engineersmnky 提到的,可能有用:
- 圆点
.
是相对路径,表示只会在节点内搜索。
- 双斜杠“//”表示该节点内的任何位置;
- 其中单斜杠“/”只是直系后代。
- Xpath Cheatsheet 可能会帮助您掌握基础知识
我尝试对一些 <li>
元素进行迭代
迭代无法按预期工作:
require 'nokogiri'
doc = Nokogiri::HTML(<<-END_OF_HTML)
<ul class="attribute_radio_list">
<li>
<input type="radio" name="group_4" value="709" id="comb_709_group_4" checked="checked">
<label for="comb_709_group_4" class="label_comb_price label_comb_price_punda comb_709_group_4 checked">
<span class="radio_label">1-10 kg</span>
<span class="price_comb">14.85 €</span>
</label>
<span class="pundaline-variations-tooltip">1-10 kg</span>
</li>
<li class=" comb_710_group_4_li" id="comb_710_group_4_li">
<input type=" radio" name="group_4" value="710" id="comb_710_group_4">
<label for="comb_710_group_4">
<span class="radio_label">10-20 kg</span>
<span class="price_comb">17.82 €</span>
</label>
<span class="pundaline-variations-tooltip">10-20 kg</span>
</li>
<li id="comb_711_group_4_li">
<input type=" radio" name="group_4" value="711" id="comb_711_group_4">
<label for="comb_711_group_4">
<span class="radio_label">20-40 kg</span>
<span class="price_comb">19.80 €</span>
</label>
<span class="pundaline-variations-tooltip">20-40 kg</span></li>
</ul>
END_OF_HTML
lis = doc.xpath("//li")
lis.each do |li|
p li.xpath("//span[@class = 'price_comb']/text()").to_s
end
returns 这个:
"14.85 €17.82 €19.80 €"
"14.85 €17.82 €19.80 €"
"14.85 €17.82 €19.80 €"
但我应该看到这个:
"14.85 €"
"17.82 €"
"19.80 €"
为什么 xpath
工作起来很奇怪,我该如何解决?
您的 XPath 表达式开头缺少一个点 .
。
而不是
"//span[@class = 'price_comb']/text()"
应该是
".//span[@class = 'price_comb']/text()"
所以整个代码片段将是:
lis.each do |li|
p li.xpath(".//span[@class = 'price_comb']/text()").to_s
end
此 XPath 表达式 //span[@class = 'price_comb']/text()
是从文档的顶部开始搜索,而不是在特定节点内。
要使其在节点内搜索,您应该以点 .
开头表达式:.//span[@class = 'price_comb']/text()
更新
正如 engineersmnky 提到的,可能有用:
- 圆点
.
是相对路径,表示只会在节点内搜索。 - 双斜杠“//”表示该节点内的任何位置;
- 其中单斜杠“/”只是直系后代。
- Xpath Cheatsheet 可能会帮助您掌握基础知识