HolyMackerel! Użyj narzędzi!
import urllib2, sys, socket, time, os
def url_tester(url = "http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz"):
file_name = url.split('/')[-1]
u = urllib2.urlopen(url,None,1) # Note the timeout to urllib2...
file_size = int(u.info().getheaders("Content-Length")[0])
print ("\nDownloading: {} Bytes: {:,}".format(file_name, file_size))
with open(file_name, 'wb') as f:
file_size_dl = 0
block_sz = 1024*4
time_outs=0
while True:
try:
buffer = u.read(block_sz)
except socket.timeout:
if time_outs > 3: # file has not had activity in max seconds...
print "\n\n\nsorry -- try back later"
os.unlink(file_name)
raise
else: # start counting time outs...
print "\nHmmm... little issue... I'll wait a couple of seconds"
time.sleep(3)
time_outs+=1
continue
if not buffer: # end of the download
sys.stdout.write('\rDone!'+' '*len(status)+'\n\n')
sys.stdout.flush()
break
file_size_dl += len(buffer)
f.write(buffer)
status = '{:20,} Bytes [{:.2%}] received'.format(file_size_dl,
file_size_dl * 1.0/file_size)
sys.stdout.write('\r'+status)
sys.stdout.flush()
return file_name
Umożliwia wydrukowanie statusu zgodnie z oczekiwaniami. Gdybym odłączyć mój kabel ethernet, otrzymuję:
Downloading: Python-2.7.3.tgz Bytes: 14,135,620
827,392 Bytes [5.85%] received
sorry -- try back later
gdybym odłączyć kabel, a następnie podłącz go z powrotem w czasie krótszym niż 12 sekund, otrzymuję:
Downloading: Python-2.7.3.tgz Bytes: 14,135,620
716,800 Bytes [5.07%] received
Hmmm... little issue... I'll wait a couple of seconds
Hmmm... little issue... I'll wait a couple of seconds
Done!
Plik został pomyślnie pobrane.
Możesz zobaczyć, że urllib2 obsługuje zarówno limity czasu, jak i ponowne połączenia. Jeśli rozłączysz się i pozostaniesz rozłączony przez 3 * 4 sekundy == 12 sekund, to na jakiś czas przestanie działać i wzniesie fatalny wyjątek. Można to również rozwiązać.
Możesz zgłosić wyjątek w swoim raporcie. – Tobold
Tak, podniesienie wyjątku wydaje się być popularnym sposobem na przerwanie pobierania, od szybkiego spojrzenia na Google. Nie jest to jednak wspomniane w dokumentacji, co niepokoi mnie, że może mieć nieoczekiwane zachowanie. Na przykład, być może dane są pobierane przez dedykowany wątek, a wyrzucenie wyjątku sprawi, że stanie się sierotą, a właściwie nie zatrzyma pobierania. – Kevin