2009-11-25 10 views
20

का उपयोग कर फ़ाइल डाउनलोड करें आंशिक डाउनलोड सुविधा का उपयोग कर HTTP पर विशाल और अभी भी बढ़ती फ़ाइल डाउनलोड करने का कोई तरीका है?आंशिक डाउनलोड (HTTP)

ऐसा लगता है कि इस कोड को डाउनलोड खरोंच से हर बार यह निष्पादित दायर:

import urllib 
urllib.urlretrieve ("http://www.example.com/huge-growing-file", "huge-growing-file") 

मैं करना चाहते हैं:

  1. लाने के लिए बस नव लिखा डेटा
  2. खरोंच से डाउनलोड केवल अगर स्रोत फ़ाइल छोटी हो जाती है (उदाहरण के लिए इसे घुमाया गया है)।

    req = urllib2.Request('http://www.python.org/') 
    req.headers['Range'] = 'bytes=%s-%s' % (start, end) 
    f = urllib2.urlopen(req) 
    

    उदाहरण के लिए::

उत्तर

40

यह रेंज हेडर का उपयोग करके आंशिक डाउनलोड करने के लिए संभव है, निम्नलिखित बाइट्स की किसी चयनित श्रेणी का अनुरोध करेंगे

>>> 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.' 

इस हेडर आप कर सकते हैं का उपयोग करना आंशिक डाउनलोड फिर से शुरू करें। आपके मामले में आपको केवल पहले ही डाउनलोड किए गए आकार का ट्रैक रखना है और एक नई श्रृंखला का अनुरोध करना है।

ध्यान रखें कि सर्वर को इस हेडर को काम करने के लिए स्वीकार करने की आवश्यकता है।

+2

इसके अलावा आपको सामग्री-श्रेणी शीर्षलेख (यह आपके द्वारा अनुरोधित सीमा से अलग हो सकता है) की जांच करनी होगी और शायद मल्टीपार्ट/बार्टेन्जेस निकाय को पार्स करने के लिए तैयार रहें। –

+2

मल्टीपार्ट/बार्टेन्जेस पहलू में चेक किया गया। Spec स्पष्ट रूप से एकल सीमा अनुरोध पर multipart/byteranges प्रतिक्रियाओं को अस्वीकार करता है। –

+2

बाकी स्थिति (एक सामान्य मामले) से पुनर्प्राप्त करने के लिए, बस बाइट्स =% डी- "' (i। ई। केवल अंतिम मूल्य के बिना) का उपयोग करें। – Alfe

0

यदि मैं आपका प्रश्न सही ढंग से समझता हूं, तो फ़ाइल डाउनलोड के दौरान बदल नहीं रही है, लेकिन नियमित रूप से अपडेट की जाती है। यदि यह सवाल है, तो rsync उत्तर है।

यदि फ़ाइल को डाउनलोड के दौरान लगातार अद्यतन किया जा रहा है, तो आपको rsync या bittorrent प्रोग्राम को संशोधित करने की आवश्यकता होगी। वे फ़ाइलों को अलग-अलग हिस्सों में विभाजित करते हैं और स्वतंत्र रूप से भाग को डाउनलोड या अपडेट करते हैं। जब आप पहली पुनरावृत्ति से फ़ाइल के अंत तक पहुंच जाते हैं, तो संलग्न चक्र को दोहराने के लिए दोहराएं; आवश्यक के रूप में जारी रखें। कम दक्षता के साथ, कोई बार बार बार rsync सकता है।

+1

HTTP के लिए एक आवश्यकता है इसलिए rsync मान्य उत्तर नहीं है –

2

टीसीपी सॉकेट और कच्चे HTTP का उपयोग करना बहुत आसान है। प्रासंगिक अनुरोध हेडर "रेंज" है।

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") 

कहाँ XXXX बाइट्स आप पहले से ही लिया गया गया है की संख्या का प्रतिनिधित्व करता है:

एक उदाहरण अनुरोध कैसा लग सकता है। फिर आप प्रतिक्रिया शीर्षलेख और सर्वर से किसी भी सामग्री को पढ़ सकते हैं। सर्वर की तरह एक हैडर देता है, तो:

Content-Length: 0 

तुम्हें पता है आप पूरी फ़ाइल मिल गया है।

यदि आप HTTP क्लाइंट के रूप में विशेष रूप से अच्छा होना चाहते हैं तो आप "कनेक्शन: रखें-जिंदा" में देख सकते हैं। शायद एक पाइथन लाइब्रेरी है जो मैंने जो कुछ भी वर्णित किया है (शायद यहां तक ​​कि urllib2 भी करता है!) लेकिन मैं एक से परिचित नहीं हूं।

+1

नादिया अलारामली का उत्तर देखें। –

+1

यदि आप टीसीपी सॉकेट के साथ अपना स्वयं का समाधान रोल करते हैं तो आप urllib2 में सभी सुविधाओं से छुटकारा पा सकते हैं, जैसे कि रीडायरेक्ट और प्रॉक्सी सेटिंग्स को संभालना। –

+0

बिल्कुल। मुझे urllib2 समर्थित मनमाने ढंग से अनुरोध शीर्षलेख याद नहीं किया गया था। यह (निश्चित रूप से) यहां जाने का सही तरीका है। –

संबंधित मुद्दे