Tracking The Packages - Page 26
January 21, 2002
Tracking Federal Express Packages
The FedEx tracking
application works great for tracking packages on the Web. It
provides detailed information on where your package is and where
it's been. Federal Express also provides an
API
for interacting with the FedEx tracking system. A Perl module is
available for this API, but the module included many other
features that we don't need and it must run on a win32 system.
Also, FedEx requires you to register a FedEx number and fill out
a form, accepting a number of licensing terms including the
restriction that the API could not be used in an application that
provided information about another carrier.
Instead of using the API, I decided that it would be simpler to
write a program using the
LWP libraries that submits the tracking number to the FedEx
Web site and parses the resulting HTML page for the results. It
did take some time to construct the regular expression, but I was
able to tune it so that the code is minimal. It is possible that
the script will break in the future if and when FedEx changes the
interface to the tracking pages. For our purposes, the solution
is short and sweet. Perhaps in the future, FedEx will relax its
terms and the author of the FedEx module will include support for
Unix in addition to win32 systems.
I created the &parse_fedex_html subroutine on
lines 60 through 89 for this purpose. Line 62 builds the URL to
get the tracking information from the FedEx Web site. Line 63
calls the get() method of the
LWP::Simple module, which sends the URL, retrieves
the data, and assigns the results to the $page
variable. If the tracking number was invalid for some reason, the
subroutine will return a 0 on line 65. Otherwise, we search the
$page variable on line 69 for the string
CLASS="resultstableheader" followed by a
</tr> tag and some text followed by a
</table> tag. We actually want to grab the
text between the </tr> and
</table> tags because it contains the tracking
information we're looking for. This text is assigned to the
$results variable on line 70.
Now that we have the block of text that contains the tracking
information, we have to break it up a bit more to get the
details. The regular expression on line 75 grabs the text between
a <tr> and </tr> tag and
assigns it to the $record variable on line 76. Line
79 contains a more complex regular expression that's actually
made up of other regular expressions on lines 72 and 73. Line 72
is matching text within a set of <td> and
</td> tags. Line 73 builds a more complex
regular expression based on the one we build on line 72. It
contains three instances of the previous regular expression
meaning that we're looking for three separate
<td> and </td> tag pairs.
These matches will contain the tracking location, date and time,
and any notes related to the package. As a result of the match on
line 79, we set tracking variables on line 80-82. This
information is then passed back as an array on line 88, where
we'll print it to the user's browser.
Tracking UPS Packages
Tracking a package with UPS is a bit simpler because we are using
the Business::UPS module. The
&parse_ups_data subroutine on lines 90 through
100 grabs the tracking information for a given UPS tracking
number. The UPStrack function on line 93 retrieves
the tracking information for a package and returns the results in
the form of a hash. The value that we're looking for is the last
location that the package was tracked. This information is
contained in the Last Scanned at hash key value.
This value is assigned on line 96 and returned to the caller on
line 99. Like I said, tracking packages with the UPS module is a
bit easier. Don't rely on the documentation that comes with the
module however. The module itself needs to be updated to handle
the latest return values from the UPS server. The module would
have been able to return more data if all of the features
were working.
Displaying the Form and Results
Now that we've covered the major sections of the script, let's
talk about the main body on lines 7 to 39. Lines 7 to 13
initialize all of the variables that we use in the application.
Line 15 prints the HTTP header; line 16 prints the top portion of
the HTML results. On line 18, we check for a value in the
$order_num variable, which was set on line 11. If it
contains a value, it means that the user entered an order number
and pressed the submit button. On line 19, we look up the
corresponding tracking number with the
&get_tracking_number subroutine. If the routine
returns a tracking number, we grab the tracking information on
line 24 or 26 with the &parse_fedex_html or
&parse_usp_data depending on whether the
$track_type variable was set to FedEx or UPS by
&get_tracking_number. If we didn't get any
errors when retrieving the tracking information, the results are
printed to the browser on lines 32 and 33. Lastly, we print the
HTML form by calling the &print_form subroutine
on line 38. This routine simply contains the HTML form into which
the user will enter their order number. The script ends on line
39 where we print </body></html> to end
the HTML output.
The resulting script will print an order number field. When an
order number is entered and the user presses the submit button,
the script attempts to lookup the tracking number and retrieve
the tracking information, which is printed back to the browser.
The same form is also printed again with the order number pre-
filled to make it easy for users to continue to track the package
as it moves from one delivery point to another.
Conclusion
You can use this script out of the box to enable your customers
to track their packages without going off your Web site or having
to keep track of a separate order and tracking number. You'll
probably want to modify the script to integrate your site's
design elements since the output of this script is minimal. As I
hope you've learned with this script, Perl is a powerful text
processing language. I could go on to integrate other carrier
tracking systems so that the script had better coverage. Another
feature that might be useful is the ability to get the price of
a package that will be shipped. Some e-commerce packages already
include this functionality, but others don't. This feature can be
added using the same techniques for the FedEx Web site and with
the Business::UPS module. If you'd like to see this feature
added, write to me at
eisen@ferrumgroup.com.
Tracking FedEx and UPS Packages Online - Page 25
Weaving Magic With Regular Expressions
|