我有一个项目列表:
<div class="item">
<a href="//external-link.com">
<img src="main-image.jpg" alt=""/>
</a>
<h2> Title </h2>
<p> Description lorem here </p>
</div>
<div class="item">
<a href="//external-link.com">
<img src="main-image.jpg" alt=""/>
</a>
<h2> Title </h2>
<p> Description lorem here </p>
</div>
<div class="item">
<a href="//external-link.com">
<img src="main-image.jpg" alt=""/>
</a>
<h2> Title </h2>
<p> Description lorem here </p>
</div>
我想提取<h2>
标记的文本,以及&#34; src&#34;和&#34; href&#34; <a>
和<img>
代码,但我无法弄清楚如何提取&#34; src&#34;和&#34; href&#34;属性。
这就像我使用的那样:
require 'nokogiri'
require 'open-uri'
pageURL = 'http://ticketdriver.com/amg/buy/tickets'
page = Nokogiri::HTML(open(pageURL), nil, 'UTF-8')
page.css('.item').each do |node|
title = node.css('h2').text
srcUrl = node.css('img')['src']
end
text
部分正在运行,但我无法访问&#34; .item&#34;的子元素的键和值。我尝试了children[0]
,[0]['src']
,[:src]
,attr()
,attribute()
等等。
我完全没有想法和Google搜索页面。
答案 0 :(得分:0)
我做的事情如下:
doc = Nokogiri::HTML(<<EOT)
<html><body>
<div class="item">
<a href="//external-link.com">
<img src="main-image1.jpg" alt=""/>
</a>
<h2> Title1 </h2>
</div>
<div class="item">
<a href="//external-link.com">
<img src="main-image2.jpg" alt=""/>
</a>
<h2> Title2 </h2>
</div>
<div class="item">
<a href="//external-link.com">
<img src="main-image3.jpg" alt=""/>
</a>
<h2> Title3 </h2>
</div>
</body></html>
EOT
items = doc.search('.item').map { |item|
{
title: item.at('h2').text,
src: item.at('img')['src']
}
}
结果是:
items
# => [{:title=>" Title1 ", :src=>"main-image1.jpg"},
# {:title=>" Title2 ", :src=>"main-image2.jpg"},
# {:title=>" Title3 ", :src=>"main-image3.jpg"}]
我故意只得到&#34; src&#34;来自<img>
标记的属性。根据上面的代码,您可以了解如何从<a>
标记中获得所需内容。
请注意,我使用的是通用search
而不是css
。 Nokogiri非常聪明,可以在大多数时间区分CSS和XPath选择器。我使用css
或xpath
的唯一时间是Nokogiri无法解决的问题。我使用CSS因为它通常更简单,更容易阅读。
另外,请注意我没有使用node.css('h2').text
。 css
返回一个NodeSet,类似于一个Array,而at
返回一个Node。在您的代码中,您可以屏蔽两者之间的差异,但使用css
,xpath
或通用search
是等待中的错误。考虑一下:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html><body>
<p>foo</p>
<p>bar</p>
<p>baz</p>
</body></html>
EOT
doc.search('p').text # => "foobarbaz"
doc.at('p').text # => "foo"
这意味着,如果search
或其中一个特定方法返回NodeSet,text
将返回该集合中所有节点的文本,这很少是您想要的。相反,您需要使用at
来查找所需的特定子节点,然后提取其文本。你如何做到这一点是一个不同的问题,但它很容易完成。