使用 Ruby 和 Nokogiri 解析页面的不同 class 项

Parsing different class items of a page with Ruby and Nokogiri

我需要解析这个网页的图片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 个项目。发生这种情况是因为当项目没有图像时,class 是 "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_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

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

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

Edit: 在没有 @data original 属性的地方获取 img,我注意到有一个不同的 class 名称,所以我们可以向 XPath 添加另一个选项,检查 img 元素的 class 名称:

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 的 class,其 src 属性
  • img 具有 image lazy 的 class,其 data-original 属性