【问题标题】:Parsing different class items of a page with Ruby and Nokogiri使用 Ruby 和 Nokogiri 解析页面的不同类项
【发布时间】:2017-07-28 04:26:24
【问题描述】:

我需要解析这个网页的图片http://www.olx.com.br/loja/id/122315

我正在尝试使用 Nokogiri 获取 img src 的链接,因为我会将这些链接保存在我的应用程序的数据库中。

这段代码获得了我需要的所有元素 (21),但我无法获得我想要的输出...

require 'open-uri'
require 'nokogiri'


site = open ('http://www.olx.com.br/loja/id/122315')
site_lido = site.read
site_html = Nokogiri::HTML(site_lido)

site_html.at_css('#main-ad-list').css('.item').css('.col-1').css('.OLXad-list-image-box').count

如果我使用此代码:

site_html.at_css('#main-ad-list').css('.item').css('.col-1').css('.OLXad-list-image-box').children.display

我得到这个输出:

<span class="no-photo">sem foto</span>

<img class="image" src="http://img.olx.com.br/thumbsli/68/689721024565019.jpg" alt="CHEVROLET ONIX 1.0 MPFI LT 8V FLEX 4P MANUAL - 2016">

<span class="no-photo">sem foto</span>

<span class="no-photo">sem foto</span>

<span class="no-photo">sem foto</span>

<span class="no-photo">sem foto</span>

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/64/640717028616332.jpg" alt="RENAULT SANDERO 1.0 EXPRESSION 16V FLEX 4P MANUAL - 2017">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/64/649717026459313.jpg" alt="HYUNDAI HB20 1.0 COMFORT 12V FLEX 4P MANUAL - 2016">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/64/643717023799626.jpg" alt="FORD ECOSPORT 2.0 SE 16V FLEX 4P POWERSHIFT - 2015">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/64/641717028095520.jpg" alt="FIAT SIENA 1.0 MPI FIRE CELEBRATION 8V FLEX 4P MANUAL - 2010">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/64/647717020502693.jpg" alt="FIAT FIORINO 1.4 MPI FURG 8V FLEX 2P MANUAL - 2016">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/64/644717022311605.jpg" alt="FIAT FIORINO 1.4 MPI FURG 8V FLEX 2P MANUAL - 2016">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/64/642717021110547.jpg" alt="CHEVROLET ONIX 1.0 MPFI LT 8V FLEX 4P MANUAL - 2016">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/59/599711024752265.jpg" alt="HONDA CRV 2009/2010 2.0 LX 4X2 16V GASOLINA 4P AUTOMTICO - 2010">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/59/597711029493606.jpg" alt="TOYOTA COROLLA 2012/2013 2.0 XRS 16V FLEX 4P AUTOMTICO - 2013">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/57/577710022331072.jpg" alt="FIAT STRADA 1.4 MPI WORKING CS 8V FLEX 2P MANUAL - 2016">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/57/573710026456008.jpg" alt="CHEVROLET ONIX 1.0 MPFI LT 8V FLEX 4P MANUAL - 2016">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/10/109713018515279.jpg" alt="Farol Traseiro Em Led Com Carregamento Usb">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/23/235706014933596.jpg" alt="Hilux 2013 SRV Diesel 4x4 - 2013">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/23/233706015584450.jpg" alt="New Fiesta 2014 1.6 Automatico - 2014">

<img class="image lazy" src="//static.bn-static.com/img-46150/desktop/transparent.png" data-original="http://img.olx.com.br/thumbsli/23/239706014799171.jpg" alt="C3 2012 1.4 Completo - 2012">

但是我需要得到这个输出,我需要把它放在一个数组上:

sem foto
http://img.olx.com.br/thumbsli/68/689721024565019.jpg
sem foto
sem foto
sem foto
sem foto
http://img.olx.com.br/thumbsli/64/640717028616332.jpg
http://img.olx.com.br/thumbsli/64/649717026459313.jpg
http://img.olx.com.br/thumbsli/64/643717023799626.jpg
http://img.olx.com.br/thumbsli/64/641717028095520.jpg
http://img.olx.com.br/thumbsli/64/647717020502693.jpg
http://img.olx.com.br/thumbsli/64/644717022311605.jpg
http://img.olx.com.br/thumbsli/64/642717021110547.jpg
http://img.olx.com.br/thumbsli/59/599711024752265.jpg
http://img.olx.com.br/thumbsli/59/597711029493606.jpg
http://img.olx.com.br/thumbsli/57/577710022331072.jpg
http://img.olx.com.br/thumbsli/57/573710026456008.jpg
http://img.olx.com.br/thumbsli/10/109713018515279.jpg
http://img.olx.com.br/thumbsli/23/235706014933596.jpg
http://img.olx.com.br/thumbsli/23/233706015584450.jpg
http://img.olx.com.br/thumbsli/23/239706014799171.jpg

如果我尝试将解析方法更改为:

site_html.at_css('#main-ad-list').css('.item').css('.OLXad-list-image-box').css('.image').each do |aaa|
    puts aaa.values
end

我可以更接近所需的输出,但我只得到 16 个项目,而不是 21 个......我需要页面的 21 个项目。发生这种情况是因为当项目没有图像时,该类是“span”而不是“image”...

我怎样才能得到想要的输出?

使用解决方案编辑(Mark Thomas 解决方案):

可以使用以下代码获得所需的输出:

array = []

site_html.css('#main-ad-list .OLXad-list-image-box').xpath('span|img[@class="image"]/@src|img[@class="image lazy"]/@data-original').each do |q|  
        array.push q.text
end

puts array

【问题讨论】:

  • 而不是遍历节点集,将每个节点推入一个数组,您可以简单地这样做:array = site_html.css('...').xpath('...').map(&amp;:text)
  • 酷。也可以用这种结构简化代码吗? categorias = [] site_html.css('#main-ad-list .OLXad-list-line-2').xpath('p[@class="text detail-category"]').each do |q| categorias.push q.children.first.text.gsub!(/[\t\n]/,"") end 我在这里尝试使用相同的简化,但出现错误。 teste = site_html.css('#main-ad-list .OLXad-list-line-2').xpath('p[@class="text detail-category"]').map(&amp;:children.first.text.gsub!(/[\t\n]/,""))
  • 使用.map{|q| q.children.first.text.strip}

标签: ruby-on-rails ruby nokogiri


【解决方案1】:

XPath 支持类似的逻辑或逻辑。如果您不害怕将 CSS 选择器与 XPath 语句结合使用:

site_html.css('#main-ad-list .OLXad-list-image-box').xpath('span|img/@data-original')

编辑:为了得到没有@data original属性的img,我注意到有一个不同的类名,所以我们可以在XPath中添加另一个选项,检查类名img 元素的:

site_html.css('#main-ad-list .OLXad-list-image-box').xpath('span|img[@class="image"]/@src|img[@class="image lazy"]/@data-original')

我将分解 XPath 部分:

span | img[@class="image"]/@src | img[@class="image lazy"]/@data-original

表示包括以下任何一项:

  • span
  • img 类为image,其src 属性
  • img 类为image lazy,其data-original 属性

【讨论】:

  • 它几乎成功了。但由于某种原因,这段代码只返回 20 个元素而不是 21 个......在第二项中它没有“原始数据”,只有 src。可以用 xpath 纠正吗?
  • 我试过这个:`site_html.at_css('#main-ad-list').css('.OLXad-list-image-box').xpath('span|img/@src |img/@data-original').每个都做 |q| puts q.text end ` 但它也占用了所有“src”itens 的链接......
  • 你知道解决第二个元素这个问题的方法吗?
  • 看来,其中 15 个类是 image lazy,我想这应该是延迟加载图像,尽管它们都没有出现在我的网络浏览器中。另一个只是类image。您当然可以为此添加更多条件逻辑。
  • 另请注意,我将您的 css 方法调用合并为一个。我的偏好是不把它们锁起来。可能表现也更好。
【解决方案2】:

我认为这可行

 array_of_items = []

 site_html.at_css('#main-ad-list').css('.item').css('.col-1').css('.OLXad-list-image-box').children.each do |child|

   array_of_items << (child.name == 'img' ? child.attr['data-original'] : child.text)

 end

【讨论】:

  • array_of_itens 的输出是:文字文字img文字文字img文字文字img文字文字img文字文字img文字文字img文字文字img文字文字img文字文字img文字没有工作......
  • 尝试将三元表达式包装在( )
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 2013-01-05
  • 2013-04-02
  • 2014-09-15
  • 1970-01-01
相关资源
最近更新 更多