从循环中获取HTML属性

时间:2015-10-12 18:35:44

标签: css ruby nokogiri

我有一个项目列表:

<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搜索页面。

1 个答案:

答案 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选择器。我使用cssxpath的唯一时间是Nokogiri无法解决的问题。我使用CSS因为它通常更简单,更容易阅读。

另外,请注意我没有使用node.css('h2').textcss返回一个NodeSet,类似于一个Array,而at返回一个Node。在您的代码中,您可以屏蔽两者之间的差异,但使用cssxpath或通用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来查找所需的特定子节点,然后提取其文本。你如何做到这一点是一个不同的问题,但它很容易完成。