Télécharger le fichier en téléchargement partiel (HTTP)
y a-t-il un moyen de télécharger un fichier énorme et en croissance sur HTTP en utilisant la fonctionnalité de téléchargement partiel?
Il semble que ce code téléchargements de fichiers à partir de zéro à chaque fois qu'il a exécuté:
import urllib
urllib.urlretrieve ("http://www.example.com/huge-growing-file", "huge-growing-file")
j'aimerais:
- Pour récupérer juste le nouvellement écrites données
- télécharger à partir de zéro seulement si le fichier source devient plus petit (par exemple, il a été mis en rotation).
3 réponses
il est possible de faire un téléchargement partiel en utilisant l'en-tête range, les suivants demanderont une plage sélectionnée d'octets:
req = urllib2.Request('http://www.python.org/')
req.headers['Range'] = 'bytes=%s-%s' % (start, end)
f = urllib2.urlopen(req)
Par exemple:
>>> req = urllib2.Request('http://www.python.org/')
>>> req.headers['Range'] = 'bytes=%s-%s' % (100, 150)
>>> f = urllib2.urlopen(req)
>>> f.read()
'l1-transitional.dtd">\n\n\n<html xmlns="http://www.w3.'
en utilisant cet en-tête, vous pouvez reprendre des téléchargements partiels. Dans votre cas, tout ce que vous avez à faire est de garder une trace de la taille déjà téléchargée et demander une nouvelle gamme.
Gardez à l'esprit que le serveur doivent accepter cet en-tête pour que cela fonctionne.
c'est assez facile à faire en utilisant les sockets TCP et le HTTP brut. L'en-tête de requête concerné est"Range".
une requête d'exemple peut ressembler à:
mysock = connect(("www.example.com", 80))
mysock.write(
"GET /huge-growing-file HTTP/1.1\r\n"+\
"Host: www.example.com\r\n"+\
"Range: bytes=XXXX-\r\n"+\
"Connection: close\r\n\r\n")
où XXXX représente le nombre d'octets que vous avez déjà récupérés. Ensuite, vous pouvez lire les en-têtes de réponse et n'importe quel contenu du serveur. Si le serveur renvoie un en-tête comme:
Content-Length: 0
vous savez que vous avez le dossier entier.
si vous voulez être particulièrement gentil en tant que client HTTP vous pouvez regarder dans "Connexion: keep-alive". Peut-être qu'il y a une bibliothèque python qui fait tout ce que j'ai décrit (peut-être même urllib2 le fait!) mais je ne suis pas familier avec.
si je comprends votre question correctement, le fichier ne change pas pendant le téléchargement, mais est mis à jour régulièrement. Si c'est la question, rsync est la réponse.
si le fichier est mis à jour continuellement, y compris pendant le téléchargement, vous aurez besoin de modifier rsync ou un programme bittorrent. Ils divisent les fichiers en morceaux séparés et téléchargent ou mettent à jour les morceaux indépendamment. Lorsque vous arrivez à la fin du fichier de la première itération, répéter pour obtenir le annexée morceau; continuer comme nécessaire. Avec moins d'efficacité, on pourrait simplement rsync à plusieurs reprises.