Let us download the Python 2.7 code from http://www.python.org. A resume_download() file will resume any unfinished download of that file.
Listing 4.9 explains resume downloading as follows:
#!/usr/bin/env python # Python Network Programming Cookbook -- Chapter - 4 # This program requires Python 3.5.2 or any later version # It may run on any other version with/without modifications. # # Follow the comments inline to make it run on Python 2.7.x. import urllib.request, urllib.parse, urllib.error # Comment out the above line and uncomment the below for Python 2.7.x. #import urllib import os TARGET_URL = 'http://python.org/ftp/python/2.7.4/' TARGET_FILE = 'Python-2.7.4.tgz' class CustomURLOpener(urllib.request.FancyURLopener): # Comment out the above line and uncomment the below for Python 2.7.x. #class CustomURLOpener(urllib.FancyURLopener): """Override FancyURLopener to skip error 206 (when a partial file is being sent) """ def http_error_206(self, url, fp, errcode, errmsg, headers, data=None): pass def resume_download(): file_exists = False CustomURLClass = CustomURLOpener() if os.path.exists(TARGET_FILE): out_file = open(TARGET_FILE,"ab") file_exists = os.path.getsize(TARGET_FILE) #If the file exists, then only download the unfinished part CustomURLClass.addheader("range","bytes=%s-" % (file_exists)) else: out_file = open(TARGET_FILE,"wb") web_page = CustomURLClass.open(TARGET_URL + TARGET_FILE) #Check if last download was OK if int(web_page.headers['Content-Length']) == file_exists: loop = 0 print ("File already downloaded!") byte_count = 0 while True: data = web_page.read(8192) if not data: break out_file.write(data) byte_count = byte_count + len(data) web_page.close() out_file.close() for k,v in list(web_page.headers.items()): # Comment out the above line and uncomment the below for Python 2.7.x. #for k,v in web_page.headers.items(): print (k, "=",v) print ("File copied", byte_count, "bytes from", web_page.url) if __name__ == '__main__': resume_download()
Executing this script will result in the following output:
$ python 4_9_http_fail_over_client.py content-length = 14489063 content-encoding = x-gzip accept-ranges = bytes connection = close server = Apache/2.2.16 (Debian) last-modified = Sat, 06 Apr 2013 14:16:10 GMT content-range = bytes 0-14489062/14489063 etag = "1748016-dd15e7-4d9b1d8685e80" date = Tue, 07 May 2013 12:51:31 GMT content-type = application/x-tar File copied 14489063 bytes from http://python.org/ftp/python/2.7.4/Python-2.7.4.tgz