【问题标题】:Parse image url nokogiri解析图片 url nokogiri
【发布时间】:2013-10-23 08:02:20
【问题描述】:

我需要从 HTML 中解析出图像 URL,如下所示:

<p><a href="http://blog.website.com/wp-content/uploads/2012/02/image_name.jpg" ><img class="aligncenter size-full wp-image-12313" alt="Example image Name" src="http://blog.website.com/wp-content/uploads/2012/02/image_name.jpg" width="630" height="119" /></a></p>

到目前为止,我正在使用 Nokogiri 解析 &lt;h2&gt; 标签:

require 'rubygems'
require 'nokogiri'
require 'open-uri'

page = Nokogiri::HTML(open("http://blog.website.com/"))
headers = page.css('h2')

puts headers.text

我有两个问题:

  1. 如何解析出图片网址?
  2. 理想情况下,我会以这种格式打印到控制台:
1. 标题 1 图片网址 1 image_url 2(如果有) 2. 标题 2 2image_url 1 2image_url 2(如果有)

到目前为止,我还无法以这种漂亮的格式打印我的标题。我该怎么做?

<h2><a href="http://blog.website.com/2013/02/15/images/" rel="bookmark" title="Permanent Link to Blog Post">Blog Post</a></h2>
          <p class="post_author"><em>by</em> author</p>
          <div class="format_text">
    <p style="text-align: left;">Blog Content </p>
<p style="text-align: left;"> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
<p style="text-align: center;"><a href="http://blog.website.com/wp-content/uploads/2012/02/image21.jpg" ><img class="alignnone size-full wp-image-23382" alt="image2" src="http://blog.website.com/wp-content/uploads/2012/02/image21.jpg" width="630" height="210" /></a></p>
<p style="text-align: left;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
<p style="text-align: center;"><b id="internal-source-marker_0.054238131968304515">Items: <a href="http://www.website.com/threads?src=login#/show/thread/A_abvaf812e3"  target="_blank">Items for Spring</a></b></p>
<p style="text-align: center;">Lorem Ipsum.</p>
<p style="text-align: center;"><b id="internal-source-marker_0.054238131968304515">More Items: <a href="http://www.website.com/threads#/show/thread/A_abv2a6822e2"  target="_blank">Lorem Ipsum</a></b></p>
<p style="text-align: center;">Lorem Ipsum.</p>
<p style="text-align: center;"><b id="internal-source-marker_0.054238131968304515">Still more items: <a href="http://www.website.com/threads#/show/thread/A_abv7af882e3"  target="_blank">Items:</a></b></p>
<p style="text-align: center;">Lorem Ipsum.</p>
<p style="text-align: center;"><b id="internal-source-marker_0.054238131968304515">Lorem ipsum: <a href="http://www.website.com/threads?src=login#/show/thread/A_abvea6832e8"  target="_blank">Items</a></b></p>
<p style="text-align: center;">Lorem Ipusm</p>
<p style="text-align: center;"><b id="internal-source-marker_0.054238131968304515">
        </div>  
          <p class="to_comments"><span class="date">February 15, 2013</span> &nbsp; <span class="num_comments"><a href="http://blog.website.com/2013/02/15/Blog-post/#respond" title="Comment on Blog Post">No Comments</a></span></p>

【问题讨论】:

  • Image scraping in Ruby的可能重复
  • 示例 HTML 将有助于解决您希望将图像与其标题相关联的部分问题。
  • 我添加了一些示例 html(添加了 lorem ipsums 并隐藏了网站)。我正在寻找解析第三个

    中的图像并将其与标题标题相关联。

  • 我在答案中包含了我最终使用的代码。

标签: ruby parsing nokogiri


【解决方案1】:

我认为先按 h2 分组更有意义:

doc.search('h2').each_with_index do |h2, i|
  puts "#{i+1}."
  puts h2.text
  h2.search('+ p + div > p[3] img').each do |img|
    puts img['src']
  end
end

【讨论】:

  • 这不会获取所有图像;只有在他的一个例子中显示的确切结构内的那些。
  • 对。这就是他所要求的。
  • 好吧,他没有示例说明“图片 url 2(如果有)”可能出现的位置。
  • 他特别提到了第 3 页。不过没关系,很容易适应情况。
  • 可以调整它以适应 any 图像直到下一个h2?我试图找到一种方法,我唯一想到的就是我发布的由内而外的解决方案。
【解决方案2】:

要获取图像,只需查找带有src 属性的img 标记。

如果您希望h2 与每张图片相关联,您可以这样做:

doc.xpath('//img').each do |img|
  puts "Header: #{img.xpath('preceding::h2[1]').text}"
  puts "  Image: #{img['src']}"
end

请注意,切换到 XPath 是为了 preceding:: 轴。

编辑

要按标题分组,您可以将它们放在哈希中:

headers = Hash.new{|h,k| h[k] = []}
doc.xpath('//img').each do |img|
  header = img.xpath('preceding::h2[1]').text
  image = img['src']
  headers[header] << image
end

要获得您规定的输出:

headers.each do |h,urls|
  puts "#{h} #{urls.join(' ')}"
end

【讨论】:

  • 酷,有没有与“先行”相反的方法?比如下面?
  • 这很有帮助,但我实际上对相反的感兴趣。标题,然后是以下图像。有没有办法使用与您提供的技术接近的技术来做到这一点?
  • 我试过了: doc.xpath('//h2/a[@rel = "bookmark"]').each do |header| puts "Header: #{header.text}" puts " Image: #{header.xpath('following::img[1]')['src']}" end 但我得到一个 "Can't convert String into整数(类型错误)
  • 不,你不能反其道而行之,因为无论中间是否有h2,你都会得到所有的图像。您仍然可以按照我在每个标题下显示和分组图像的方式进行操作。
  • 当我用 puts " Image 1: #{header.xpath('following::img[1]').to_s} 执行上面两个 cmets 的代码时,我得到 blog.website.com/wp-content/uploads/2012/02/image21.jpg" width="630" height="210" />
【解决方案3】:

我最终使用的代码。随意批评(我可能会从中学习):

require 'rubygems'
require 'nokogiri'

doc = Nokogiri::HTML(open("http://blog.website.com/"))

doc.xpath('//h2/a[@rel = "bookmark"]').each_with_index do |header, i|
  puts i+1
  puts " Title: #{header.text}"
  puts "  Image 1: #{header.xpath('following::img[1]')[0]["src"]}"
  puts "  Image 2: #{header.xpath('following::img[2]')[0]["src"]}"
end

【讨论】:

  • 不,following::img 将拾取超过下一个 h2 的图像,如果 [0]["src"] 不存在,则会导致错误。另外,尽可能使用 css。
  • 此代码适用于我正在使用的网页,而您提供的代码省略了一些图像(尽管经过一些调整,我确信它会起作用)。我确定这是因为您没有完整的信息。
  • following::img[1] 没有跳过 h2 的原因是因为有像 img[0] 这样的 Facebook 图像,我不在乎。幸运的是,整个页面的格式是一致的。
【解决方案4】:

我曾经做过类似的事情(实际上我想要完全相同的输出)。这个解决方案很容易理解:

根据 DOM 的结构,您可以执行以下操作:

body = page.css('div.format_text')
headers = page.css('div#content_inner h2 a')
post_counter = 1

body.each_with_index do |body,index| 
   header = headers[index]
   puts "#{post_counter}. " + header
   body.css('p a img, div > img').each{|img| puts img['src'] if img['src'].match(/\Ahttp/) }
   post_counter += 1
end

因此,基本上,您正在检查每个带有 1 个或多个图像的标题。我正在解析的页面有图像 div 之外的标题,这就是为什么我使用两个不同的变量来查找它们(正文/标题)。此外,我在查找图像时定位了两个类,因为这是这个特定 DOM 的结构方式。

这应该会给你一个你想要的干净的输出。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2013-02-01
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    • 2011-01-27
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    相关资源
    最近更新 更多