#!/usr/bin/perl use LWP::UserAgent; use HTML::Form; use Date::Manip; # CPAN use HTML::TreeBuilder; # CPAN ###################################################################### # Send the password form and check for success. # # @param $form the form to send. sub send_pw { my $form = shift; print "sending password\n"; # [1] Build request from the form my $request = $form->click(); # [2] Pass request to the user agent and get a response back my $response = $ua->request($request); # [3] Check the outcome of the response if (! $response->is_success) { die "Can't send password.\n"; } return 0; } ###################################################################### # Bid for an auction. # # @param $username the user # @param $password the password of this user # @param $form the form to submit. sub send_bid { my $ret; my $username = shift; my $password = shift; my $form = shift; # we start without sucess... $ret = 1; print "sending bid\n"; # [1] Build request from the form my $request = $form->click(); # [2] Pass request to the user agent and get a response back my $response = $ua->request($request); # [3] Check the outcome of the response if (! $response->is_success) { die "Can't send bid.\n"; } # [4] Get all forms and find the right one to set the username and password @forms = HTML::Form->parse($response->content, $response->base()); foreach $form (@forms) { $username_input = $form->find_input("user"); $password_input = $form->find_input("pass"); # the form must have a user and password field if ( $username_input != undef && $password_input != undef ) { $username_input->value($username); $password_input->value($password); $ret = send_pw($form); } } return $ret; } ###################################################################### # Bid for an auction. # # @param $number the article to buy # @param $username the user # @param $password the password of this user # @param $maxbid the maximum bid sub bid { my $ret; my $number = shift; my $username = shift; my $password = shift; my $maxbid = shift; # we start without sucess... $ret = 1; # [1] Create a request my $request = HTTP::Request->new(GET => 'http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=' . $number); # [2] Pass request to the user agent and get a response back my $response = $ua->request($request); # [3] Check the outcome of the response if (! $response->is_success) { die "Can't contact ebay for article.\n"; } # [4] Get all forms and find the right one @forms = HTML::Form->parse($response->content, $response->base()); foreach $form (@forms) { $maxbid_input = $form->find_input("maxbid"); # the form must contain a field named "maxbid". if ( defined($maxbid_input) ) { $maxbid_input->value($maxbid); $ret = send_bid($username, $password, $form); } } return $ret; } ###################################################################### # Get the number of seconds until the auction ends. # # @param $number the item number of the auction sub get_secs_until_end_of_auction { my $number = shift; my $remaining_secs = 1000; # [1] Create a request my $request = HTTP::Request->new(GET => 'http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=' . $number); # [2] Pass request to the user agent and get a response back my $response = $ua->request($request); # [3] Check the outcome of the response if (! $response->is_success) { warn "Can't contact ebay for articel.\n"; } # [4] Build the HTML tree and look for the title element my $tree = HTML::TreeBuilder->new; $tree->parse($response->content); my $title = $tree->look_down('_tag', 'title'); if ($title) { # the title contains something like: # "eBay item 27323776XX (Ends Jun-04-03 14:04:04 PDT) - Laptop..." $title_string = $title->as_text; # [4.1] Find out the date inside the brackets if ( $title_string =~ /\(\S+\s+(.*)\)/ ) { # [4.1.1] Parse the date of the auction and "today" $secs_to_end = &UnixDate($1,"%s"); $secs_to_now = &UnixDate("today","%s"); # [4.1.2] Compute the remaining seconds $remaining_secs = $secs_to_end - $secs_to_now; } } else { warn "No title in article"; } $tree->delete; return $remaining_secs; } ###################################################################### # Wait for the end of the auction. # # @param $number the item number of the auction # sub wait_for_end_of_auction { my $ret; my $number = shift; print "waiting for end of auction... "; # [1] Get the number of seconds until the auction ends $secs = get_secs_until_end_of_auction($number); # [2] Wait this time while ($secs > 400 ) { print " $secs"; sleep(300); # [2.1] resynchronize again $secs = get_secs_until_end_of_auction($number); } # [3] add 10 more seconds until the auction ends $secs = $secs + 10; # [4] ... and wait print "Last sleep for $secs seconds.\n"; sleep($secs); } ###################################################################### # Print the winner of the auction. # # @param $number the item number of the auction sub print_winner_of_auction { my $number = shift; my $remaining_secs = 1000; # [1] Create a request my $request = HTTP::Request->new(GET => 'http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=' . $number); # [2] Pass request to the user agent and get a response back my $response = $ua->request($request); # [3] Check the outcome of the response if (! $response->is_success) { warn "Can't contact ebay for articel.\n"; } # [4] Build the HTML tree and look for the title element if ( $response->content =~ /ReturnUserEmail&requested=(\w+)&/ ) { print "The winner is: $1\n"; } else { warn "No winner could be found."; } } $| = 1; if ( $#ARGV != 3 ) { die "usage: ebay.pl number username password maximum-bid\n"; } $number = shift; $username = shift; $password = shift; $maxbid = shift; # [1] Build the user agent $ua = LWP::UserAgent->new; # [2] Bid bid($number, $username, $password, $maxbid); # [3] Wait for end wait_for_end_of_auction($number); # [4] Check for success print_winner_of_auction($number);