1.6 to 1.8 problem?

I’m trying to run this ruby script from a magazine, so there are no typoes,
etc. Here’s the error I get…

D:>ruby test.rb
test.rb:29:in get_rank_for': Couldn't find sales rank in page (RuntimeError) from test.rb:61:invalue’
from test.rb:61
from test.rb:61:in `collect’
from test.rb:61

···

and here’s the code

#!/usr/bin/eval ruby -w
require 'net/http’
require ‘uri’

URLS = [
[“www.amazon.com”, “/exec/obidos/ASIN/020161622X/o” ],
[“www.amazon.com”, “/exec/obidos/ASIN/0201710897” ],
[“www.amazon.co.jp”, “/exec/obidos/ASIN/0201710897” ],
[“www.amazon.co.jp”, “/exec/obidos/ASIN/4894714531” ],
[“www.amazon.co.jp”, “/exec/obidos/ASIN/4894712741” ]
]

Use HTTP to fetch the page. Most of the code is redirect handling

def get_rank_for(host, path, port=80)

loop do
http = Net::HTTP.new(host, port)
resp = http.get2(path)

  case resp.code

  when "200"
     data  = resp.body

     return $1 if data =~ /Sales Rank:.*?\n?([0-9,]+)/
     return $1 if data =~ /Amazon.co.jp.*?:.*?\n([0-9,]+)/

     raise "Couldn't find sales rank in page"

  when "301", "302", "303"    # retry

     uri = URI.parse(resp['location'])

     host     = uri.host if uri.host
     port     = uri.port if uri.port
     new_path = uri.path if uri.path

     if new_path[0,1] == '/'
        path = new_path
     else
        path = File.join(File.dirname(path), path)
     end

     http.finish if http.active?

  else
     raise "Error #{resp.code} from #{host}#{path}"
  end

end
end

Fire off a thread for each request

threads = URLS.collect do |url|
Thread.new(*url) do |*a_url|
get_rank_for(*url)
end
end

Collect the results as the threads finish

ranks = threads.collect {|t| t.value }

print Time.now.strftime("%Y/%m/%d %H:%M “)
ranks.each {|r| printf(”%7s", r) }
puts

Hmm… looks familiar… :slight_smile:

It looks like Amazon.co.jp has changed their page layout, so the regexp
no longer finds the sales rank. I don’t believe Ruby versions facto
into it.

Cheers

Dave

···

On Mar 15, 2004, at 21:20, bob wrote:

I’m trying to run this ruby script from a magazine, so there are no
typoes,
etc. Here’s the error I get…

I’m trying to run this ruby script from a magazine, so there are no typoes,
etc. Here’s the error I get…

D:>ruby test.rb
test.rb:29:in get_rank_for': Couldn't find sales rank in page (RuntimeError) from test.rb:61:in value’
from test.rb:61
from test.rb:61:in `collect’
from test.rb:61


and here’s the code

#!/usr/bin/eval ruby -w
require ‘net/http’
require ‘uri’

URLS = [
[“www.amazon.com”, “/exec/obidos/ASIN/020161622X/o” ],
[“www.amazon.com”, “/exec/obidos/ASIN/0201710897” ],
[“www.amazon.co.jp”, “/exec/obidos/ASIN/0201710897” ],
[“www.amazon.co.jp”, “/exec/obidos/ASIN/4894714531” ],
[“www.amazon.co.jp”, “/exec/obidos/ASIN/4894712741” ]
]

You may care to try the Ruby/Amazon library. It uses Amazon’s XML over
HTTP (REST) interface to query the Amazon Web Services (AWS) API.

Using that, your code becomes quite simple:

[ianmacd@sagan]$ irb --simple-prompt ~/src/ruby-amazon-0.7.5/lib

require ‘amazon/search’
=> true
include Amazon::Search
=> Object
req = Request.new
=> #<Amazon::Search::Request:0x40126660 @locale=“us”, @id=“calibanorg-20”, @config={“associate”=>“calibanorg-20”, “locale”=>“us”, “dev_token”=>“xxxxxxxxxxxxxx”, “password”=>“mitja”, “email”=>“ian@caliban.org”}, @token=“xxxxxxxxxxxxxx”, @user_agent=“Ruby/Amazon 0.7.5”, @conn=#<Net::HTTP xml.amazon.com:80 open=true>>
puts req.asin_search(‘020161622X’).products[0].sales_rank
6921
=> nil
puts req.asin_search(‘0201710897’).products[0].sales_rank
55377
=> nil

It also works for other locales. Its RAA page is here:

http://raa.ruby-lang.org/list.rhtml?name=ruby-amazon

Ian

···

On Tue 16 Mar 2004 at 12:20:47 +0900, bob wrote:

Ian Macdonald | America has been discovered before, but it
System Administrator | has always been hushed up. – Oscar Wilde
ian@caliban.org |
http://www.caliban.org |
>