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:

  1. Pour récupérer juste le nouvellement écrites données
  2. télécharger à partir de zéro seulement si le fichier source devient plus petit (par exemple, il a été mis en rotation).
21
demandé sur Paul D. Waite 2009-11-25 21:10:02

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.

42
répondu Nadia Alramli 2009-11-25 18:31:12

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.

2
répondu Conrad Meyer 2009-11-25 18:24:41

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.

-1
répondu mpez0 2009-11-25 18:21:24