0

Nokogiri を使用してhttp://www.example.com/view-books/0/new-releasesをスクレイピングできますが、すべてのページをスクレイピングするにはどうすればよいですか? これは 5 ページありますが、最後のページがわからない場合はどうすればよいですか?

これは私が書いたプログラムです:

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

urls=Array['http://www.example.com/view-books/0/new-releases?layout=grid&_pop=flyout',
           'http://www.example.com/view-books/1/bestsellers',
           'http://www.example.com/books/pre-order?query=book&cid=1&layout=list&ref=4b116001-01a6-4f53-8da7-945b74fdb253'
      ]

@titles=Array.new
@prices=Array.new
@descriptions=Array.new
@page=Array.new

urls.each do |url|
  doc=Nokogiri::HTML(open(url))
  puts doc.at_css("title").text

  doc.css('.fk-inf-scroll-item').each do |item|
   @prices << item.at_css(".final-price").text
   @titles << item.at_css(".fk-srch-title-text").text
   @descriptions << item.at_css(".fk-item-specs-section").text
   @page << item.at_css(".fk-inf-pageno").text rescue nil
  end

  (0..@prices.length - 1).each do |index|
    puts "title: #{@titles[index]}"
    puts "price: #{@prices[index]}"
    puts "description: #{@descriptions[index]}"
  #  puts "pageno. : #{@page[index]}"
    puts ""
  end
end

CSV.open("result.csv", "wb") do |row|
  row << ["title", "price", "description","pageno"]
  (0..@prices.length - 1).each do |index|
    row << [@titles[index], @prices[index], @descriptions[index],@page[index]]
  end
end

ご覧のとおり、URL をハードコーディングしました。本のカテゴリ全体をスクレイピングすることをどのように提案しますか? 私はアネモネを試していましたが、うまくいきませんでした。

4

2 に答える 2

2

より多くの結果をロードしたときに正確に何が起こるかを調べると、実際には JSON を使用してオフセット付きの情報を読み取っていることがわかります。

したがって、次のように 5 ページを取得できます。

http://www.flipkart.com/view-books/0/new-releases?response-type=json&inf-start=0
http://www.flipkart.com/view-books/0/new-releases?response-type=json&inf-start=20
http://www.flipkart.com/view-books/0/new-releases?response-type=json&inf-start=40
http://www.flipkart.com/view-books/0/new-releases?response-type=json&inf-start=60
http://www.flipkart.com/view-books/0/new-releases?response-type=json&inf-start=80

基本的に、最後のページになるはずの値よりも小さい値inf-startが得られるまで、インクリメントを続けて結果を取得します。result-set20

于 2012-09-04T08:37:34.110 に答える
1

これは、あなたがしていることを実行するためのテストされていないコードのサンプルですが、もう少し簡潔に書かれています。

require 'nokogiri'
require 'open-uri'
require 'csv'

urls = %w[
  http://www.flipkart.com/view-books/0/new-releases?layout=grid&_pop=flyout
  http://www.flipkart.com/view-books/1/bestsellers
  http://www.flipkart.com/books/pre-order?query=book&cid=1&layout=list&ref=4b116001-01a6-4f53-8da7-945b74fdb253
]

CSV.open('result.csv', 'wb') do |row|

  row << ['title', 'price', 'description', 'pageno']

  urls.each do |url|

    doc = Nokogiri::HTML(open(url))
    puts doc.at_css('title').text

    doc.css('.fk-inf-scroll-item').each do |item|

      page = {
        titles:       item.at_css('.fk-srch-title-text').text,
        prices:       item.at_css('.final-price').text,
        descriptions: item.at_css('.fk-item-specs-section').text,
        pageno:       item.at_css('.fk-inf-pageno').text rescue nil,
      }

      page.each do |k, v|
        puts '%s: %s' % [k.to_s, v]
      end

      row << page.values
    end
  end
end

取得する必要のあるレコードの数を把握するために使用できる便利なデータがいくつかあります。

var config = {container: "#search_results", page_size: 20, counterSelector: ".fk-item-count", totalResults: 88, "startParamName" : "inf-start", "startFrom": 20};

値にアクセスするには、次のようなものを使用します。

doc.at('script[type="text/javascript+fk-onload"]').text =~ /page_size: (\d+).+totalResults: (\d+).+"startFrom": (\d+)/
page_size, total_results, start_from = $1, $2, $3
于 2012-09-05T06:18:03.333 に答える