Welcome, guest | Sign In | My Account | Store | Cart

This short script allows a user to track the current status of a package sent through FedEx. It is meant to be run from the command line and takes 1 option argument (-v) to determine whether or not it shows all tracking information, or just the most recent entry. The user can enter multiple tracking numbers at run time.

Python, 99 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
"""
This script uses the FedEx web site to download tracking information
from the web form.

Current version has US and English hardcoded in the URL.  Should be trivial to modify to support other locations/locales.

Version history

1.0     12/6/03     CBM     Initial Release
"""
__version__="1.0"
__author__="Chris Moffitt"

import sgmllib, urllib, httplib
import string
import sys, os
from optparse import OptionParser


class FedexParser(sgmllib.SGMLParser):
    """Parse the return from the FedEx site"""
    
    def __init__(self, verbose =0):
        self.results = ""
        sgmllib.SGMLParser.__init__(self, verbose)
        self.inResultsTable = False
        self.output = []
        self.tempout = []
        self.inTable = False
        self.inTD = False
        self.inResultsArea = False
        self.inTR = False
        self.collectResults = False

    def start_td(self, args="none"):
        self.inTD = True
        
    def end_td(self, args="none"):
        self.inTD = False
        
    def start_tr(self, args="none"):
        self.inTR = True

    def end_tr(self, args="none"):
        self.inTR = False
        if self.collectResults:
            self.output.append(self.tempout)
            self.tempout = []
        if self.inResultsArea:
            self.collectResults = True
           
    def start_table(self, args="none"):
        self.inTable = True
        
    def end_table(self, args="none"):
        self.inTable = False
        self.collectResults = False
        self.inResultsArea = False

    def handle_data(self, data):
        if self.inTD and self.inTable and self.inTR and "Scan Activity" in data:
            self.inResultsArea = True
        if self.collectResults and self.inTD:
            self.tempout.append(string.rstrip(data))
            
    def returnresults(self):
        return(self.output)

if __name__ == '__main__':
    usage = "usage: %prog [-v] firstTracking# secondTracking#"
    parser = OptionParser(usage, version="%prog 1.0")
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose",
                      help="Display all tracking data")
    (options, args) = parser.parse_args()
    if len(args) < 1:
        parser.error("Must enter at least one item to track")

    for num in args:
        readFedEx = FedexParser()
        postData = urllib.urlencode( {"action":"track",
                                       "cntry_code":"ca_english",
                                       "tracknumbers":num} )
        fedExURL = "http://www.fedex.com/cgi-bin/tracking?%s" % postData
        fedExPost = urllib.urlopen(fedExURL)
        fedExResults = fedExPost.read()
        fedExPost.close()
        readFedEx.feed(fedExResults)
        readFedEx.close()
        results = readFedEx.returnresults()
        print "Tracking Results for %s:" % num
        if len(results) < 2:
            print "Error - Invalid tracking number\n"
            continue
        if options.verbose:
            for line in results:
                print string.join(line),"\n"
        else:
            print string.join(results[0]),"\n"

    
    

The FedEx site allows you to track groups of packages by tracking number, but it only allows a max of 25 numbers. It also takes some time to open up the page and enter the numbers. This program makes it easier to track from the command line as well as making it easy to modify so that you could pull the numbers from a database, text file or some other source and check en masse.

The real magic of the code is the sgmllib.SGMLParser which parse the output from FedEx's cgi script.