使用 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
属性
我需要解析这个网页的图片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
属性