John Bokma Perl
freelance Perl programmer

Froogle program with currency conversion

Compare prices | 1 comment

If you use Froogle a lot to do price comparisons and end up converting each price you find to your own valuta this Perl program might come in handy. It uses XE.com to obtain the actual conversion rate. Since XE.com forbids automatic extraction this program is an example for educational purposes only.

You can pass a valuta code as the first argument to the program. The code must has a minus sign in front. When no code is given all prices are as given by Froogle (US dollars).

The Perl program first attempts to get at most 25 results form Froogle, price sorted low to high (scoring=p). The results are in HTML table cells, so HTML::Treebuilder is used to obtain those cells.

If there are results and the valuta code is not USA, the conversion factor to the given valuta is obtained from XE.com. Otherwise the conversion factor is set to 1.

Then for each table cell the title of the product and the price is extracted and printed.

# froogle.pl - Froogle with currency conversion
#
#  Copyright, 2004-2005 By John Bokma, http://johnbokma.com/
#
# This script is for educational purposes only.
#
# $Id: froogle.pl 1087 2008-09-30 19:10:04Z john $ 

use strict;
use warnings;

use URI::Escape;
use LWP::UserAgent;
use HTTP::Request::Common;

use HTML::TreeBuilder;

use constant USD => 'USD';

my $RESULTS = 25;   # max number of results


unless ( @ARGV ) {

    print "usage: froogle.pl [-valuta] term\n";
    print "    example: froogle.pl -eur sempron 3100\n";
    exit( 1 );
}

my $to = USD;
if ( index( $ARGV[0], '-' ) == 0 ) {

    $to = uc substr shift, 1;
}

my $url =

    "http://froogle.google.com/froogle?as_q=" .
    uri_escape( join ' ' => @ARGV ) .
    "&num=$RESULTS&scoring=p"
    ;

# parse the content into a tree
my $root = HTML::TreeBuilder->new_from_content(

    get_content( GET $url )
);

# get all td elements that contain a result
my @td = $root->look_down( _tag => 'td', 'class' => 'j' );

if ( @td ) {

    my $rate = $to eq USD ? 1 : xe( $to );

    for my $td ( @td ) {

        my $title = $td->look_down( _tag => 'a' )->as_text;

        my $green_text = $td->look_down(

            '_tag'  => 'font',
            'color' => '#008000'
        );

        # get the price without the $ sign
        my $price = substr(

            $green_text->look_down( _tag => 'b' )->as_text,
            1
        );

        printf "%10.2f - %s\n", $price * $rate, $title;
    }

} else {

    print "No result\n";
}

# clean up
$root->delete;

exit;


sub xe {

    my ( $to ) = @_;

    my $content = get_content(

        POST 'http://www.xe.com/ucc/convert.cgi',
            [ Amount => 1, From => USD, To => $to ]
    );

    my ( $rate ) = $content =~ /1 USD = (\S+)/;
    defined $rate or die "No rate found for valuta code '$to'\n";

    return $rate;
}


sub get_content {

    my ( $action ) = @_;

    # sets agent to circumvent 'bot' checking
    my $ua = LWP::UserAgent->new( agent => 'Mozilla/5.0' );
    my $response = $ua->request( $action );

    $response->is_success or
        die $action->uri, ": ", $response->status_line;

    return $response->content;
}

Examples of program usage and output:

froogle.pl -mxn sempron 2400    
:
:
    714.47 - Sempron 2400+, Socket A
    714.47 - Sempron 2400+, Socket A
    717.66 - AMD (SDA2400BOX) Sempron 2400+ PIB
    717.66 - CPU AMD|Semprn 1.66GHZ SDA2400DUT3D
    717.66 - CPU AMD|Semprn 1.66GHZ SDA2400DUT3D
    720.06 - Sempron 2400+ PIB
    721.08 - SDA2400BOX
    724.96 - Sempron 2400+ PIB
    725.64 - Sempron 2400+ (1.667 Clockspeed) 167FSB
    728.83 - AMD Sempron 2400+ PIB SDA2400BOX
    729.06 - SDA2400BOX
    733.38 - AMD Sempron 2400+ 1.667GHz 256k 333MHz CPU Retail
    735.66 - AMD Sempron 2400+ 1.667GHz 256k 333MHz CPU Retail

This shows the (partial) output of a froogle for the AMD Sempron 2400 with prices converted to pesos (Mexico).

Links

Please post a comment | read 1 comment by John | RSS feed