Hack 67 Tracking Packages with FedEx

figs/moderate.gif figs/hack67.gif

When you absolutely , positively have to know where your package is right now!

So many times when using the Web, all you need is one bit of information, especially when you're running a specific search. You want to know when your flight is coming in. You want to know how much a book costs. You want to know when your FedEx package is going to arrive .

Spidering is ideal for grabbing this one bit of information without expending a lot of effort. This hack helps you track FedEx packages.

The Code

Save the following code as fedex_tracker.pl :

 #!/usr/bin/perl -w use strict; use LWP::Simple; use HTML::TableExtract; # we use the Canada/English site, because its table # of package tracking is simpler to parse than the "us". my $url_base = "http://www.fedex.com/cgi-bin/tracking?action=track".                "&cntry_code=ca_english&tracknumbers="; # woo hah. # user wants to add a new tracking number. my @tracknums; push(@tracknums, shift) if @ARGV; # user already has some data on disk, so suck it in. # we could technically add a grep on the readdir, but # we have to postprocess @files anyway, so... opendir(CWD, ".") or die $!; my @files = readdir(CWD); closedir(CWD); foreach (@files) { /fedex_tracker_(\d+).dat/; push(@tracknums, ) if ; } unless (@tracknums) { die "We have no packages to track!\n"; } my %h; undef (@h{@tracknums}); @tracknums = keys %h; # quick unique. # each tracking number, look it up. foreach my $tracknum (@tracknums) {     # suck down the data or end.     my $data = get("$url_base$tracknum") or die $!;     $data =~ s/&nbsp;/ /g; # sticky spaces.     # and load our specific tracking table in.     my $te = HTML::TableExtract->new(            headers => ["Scan Activity","Date/Time"]);     $te->parse($data); # alright, we've got everything loaded, hopefully.     # now, get the new info.     my $new_data_from_site;     foreach my $ts ($te->table_states) {        foreach my $row ($ts->rows) {            $new_data_from_site .= " " . join(', ', @$row) . "\n";        }     }     # if this is a broken tracking number,     # move on and try the other ones we have.     unless ($new_data_from_site) {        print "No data found for package #$tracknum. Skipping.\n"; next;      }     # if this package has never been tracked     # before, then we'll create a file to     # hold the data. this will be used for     # comparisons on subsequent runs.     unless (-e "fedex_tracker_$tracknum.dat") {        open(FILE, ">fedex_tracker_$tracknum.dat") or die $!;        print FILE $new_data_from_site; close (FILE);        print "Adding the following data for #$tracknum:\n";        print $new_data_from_site;     }     # if the datafile does exist, load it      # into a string, and do a simplisitic     # comparison to see if they're equal.     # if not, assume things have changed.     if (-e "fedex_tracker_$tracknum.dat") {         open(FILE, "<fedex_tracker_$tracknum.dat");         $/ = undef; my $old_data_from_file = <FILE>; close(FILE);         if ($old_data_from_file eq $new_data_from_site) {             print "There have been no changes for package #$tracknum.\n";         } else {             print "Package #$tracknum has advanced in its journey!\n";             print $new_data_from_site; # update the user.             open(FILE, ">fedex_tracker_$tracknum.dat");             print FILE $new_data_from_site; close(FILE);             # the file is updated for next compare.         }     } } 

Running the Hack

To use the script, pass a package number on the command line. If you've already entered one, the script will try to use those packages you've entered previously. When you run the script with a package number, the output will look like this:

 %  perl fedex_tracker.pl 047655634284503  Adding the following data for #047655634284503:   Departed FedEx sort facility/SACRAMENTO, CA, 08/06/2003 06:54   Scanned at FedEx sort facility/SACRAMENTO, CA, 08/06/2003 00:14   Scanned at FedEx origin location/SACRAMENTO, CA, 08/05/2003 23:57   Customer-Loaded Trailer Picked Up/SACRAMENTO, CA, 08/05/2003 00:00  There have been no changes for package #047655634284503. 

Once you've run this search, the script will create a new file, fedex_tracker_ PACKAGENUM .dat , in the same directory. In the previous example, the new file is called fedex_tracker_047655634284503.dat . Each successive run, the script will search for and update this package's information. How do you get it to stop searching for a particular package? Simply delete its .dat file.

Just because you have an existing package doesn't mean you can't continue to search for other packages. Say you run the previous search and then want to run another. This will work:

 %  perl fedex_tracker.pl 123456789  No data found for package #123456789. Skipping.  There have been no changes for package #047655634284503. 

If no data is found for a package, a .dat file will not be created for it.

Hacking the Hack

If you want to write something similar that grabs information from Amazon.com's order-tracking pages, there are a variety of things you could do.

First, you could run it from cron [Hack #90] so you'd have a daily update of where your package is. Alternatively, you could have another small script that periodically gathers up the names of the various .dat files you generate and sends them to you, so you could metatrack which packages you've tracked. Or, perhaps you want to export the package information into a comma-delimited file, in which case you'll need a permanent record of shipping progress.



Spidering Hacks
Spidering Hacks
ISBN: 0596005776
EAN: 2147483647
Year: 2005
Pages: 157

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net