Вопрос

Я пытаюсь перевести этот фрагмент кода из scrubyt в nokogiri и застрял, пытаясь записать свои результаты либо в хэш, либо в xml.В scrubyt это выглядит следующим образом:

require 'rubygems'
  require 'scrubyt'

  result_data = Scrubyt::Extractor.define do
    fetch "http://www.amazon.com/gp/offer-listing/0061673730"
    results "//div[@class='resultsset']" do
       item "//tbody/tr" do
          condition "//div[@class = 'Condition']"
          price "//span[@class = 'price']"
          shipping "//span[@class = 'price_shipping']"
       end
   end
  end
  @description = result_data.to_xml
  return @description
end

С nokogiri я могу проанализировать нужную мне информацию, но, похоже, нет быстрого способа вернуть элементы в хэш или XML-документе.Вот все, что у меня есть в нокогири.

require 'rubygems'
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open('http://www.amazon.com/gp/offer-listing/0061673730'))

doc.css('div.condition, span.price, span.price_shipping ').each do |item|
puts item.content
end 

Как можно было бы вернуть информацию об элементе либо в xml, либо в хэш?

Это было полезно?

Решение

Вы можете использовать Строитель для построения XML.

builder = Nokogiri::XML::Builder.new do |xml|
  xml.root {
    xml.items {
      doc.css('div.condition, span.price, span.price_shipping').each do |o|
        xml.item_content = o
      end
    }
  }
end

puts builder.to_xml

Другие советы

Догадаться...

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

doc = Nokogiri::HTML(open('http://www.amazon.com/gp/offer-listing/0061673730'))
builder = Nokogiri::XML::Builder.new do |xml|
xml.root {
doc.xpath('//tbody[@class="result"]').each do |res|
    xml.result {
    res.css('span.price').each do |p|
      xml.price = p.content
    end
    res.css('span.price_shipping').each do |s|
      xml.ship = s.content
    end
    }
    end
}
end
puts builder.to_xml

Полученные результаты:

<?xml version="1.0"?>
<root>
  <result>
    <price=>$6.09</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$6.48</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$7.12</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$7.31</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$7.52</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$7.52</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$11.53</price=>
  </result>
  <result>
    <price=>$7.56</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$7.61</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$7.61</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$7.95</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$7.95</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$8.59</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$8.99</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$10.05</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$10.32</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$10.32</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$10.55</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$10.56</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$11.42</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$11.59</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$11.90</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$11.95</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$12.07</price=>
    <ship=>+ $3.99</ship=>
  </result>
  <result>
    <price=>$12.35</price=>
    <ship=>+ $3.99</ship=>
  </result>
</root>

Спасибо!Это именно то, что мне нужно.Однако у меня проблемы с правильным циклом.

require 'rubygems'
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open('http://www.amazon.com/gp/offer-listing/0061673730'))
builder = Nokogiri::XML::Builder.new do |xml|
  xml.root {
    xml.item {
      doc.css('span.price').each do |o|
        xml.price = o
      doc.css('span.price_shipping').each do |o|

      end
      end
    }
  }
end

puts builder.to_xml

Это возвращает это:

<?xml version="1.0"?>
<root>
  <item>
    <price=>&lt;span class="price"&gt;$6.09&lt;/span&gt;</price=>
    <price=>&lt;span class="price"&gt;$6.48&lt;/span&gt;</price=>
    <price=>&lt;span class="price"&gt;$11.95&lt;/span&gt;</price=>
    <ship=>&lt;span class="price_shipping"&gt;+ $3.99&lt;/span&gt;</ship=>
    <ship=>&lt;span class="price_shipping"&gt;+ $3.99&lt;/span&gt;</ship=>
    <ship=>&lt;span class="price_shipping"&gt;+ $3.99&lt;/span&gt;</ship=>

  </item>
</root>

Как бы мне переписать свой код, чтобы вернуть что-то вроде этого:

<?xml version="1.0"?>
<root>
  <item>
    <price=>&lt;span class="price"&gt;$6.09&lt;/span&gt;</price=>
    <ship=>&lt;span class="price_shipping"&gt;+ $3.99&lt;/span&gt;</ship=>
  </item>
  <item>
    <price=>&lt;span class="price"&gt;$6.48&lt;/span&gt;</price=>
    <ship=>&lt;span class="price_shipping"&gt;+ $3.99&lt;/span&gt;</ship=>
  </item>
  <item>
    <price=>&lt;span class="price"&gt;$11.95&lt;/span&gt;</price=>
    <ship=>&lt;span class="price_shipping"&gt;+ $3.99&lt;/span&gt;</ship=>
  </item>  
</root>

возможно, вы захотите опустить "=" в xml.price = p.content

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top