2010-08-20 22 views
6

मैं इस कोड का उपयोग एक ज़िप फ़ाइल डाउनलोड करने का प्रयास कर रहा हूँ डाउनलोड करने के लिए:पायथन: कैसे एक ज़िप फ़ाइल

o = urllib2.build_opener(urllib2.HTTPCookieProcessor()) 

#login 
p = urllib.urlencode({ usernameField: usernameVal, passField: passVal }) 
f = o.open(authUrl, p) 
data = f.read() 
print data 
f.close() 

#download file 
f = o.open(remoteFileUrl) 
localFile = open(localFile, "wb") 
localFile.write(f.read()) 
f.close() 

मैं कुछ बाइनरी डेटा हो रही है, लेकिन फ़ाइल मैं "डाउनलोड" का आकार बहुत है छोटा और मान्य ज़िप फ़ाइल नहीं है। क्या मैं ज़िप फ़ाइल को ठीक से पुनर्प्राप्त नहीं कर रहा हूं? f = o.open(remoteFileUrl) के लिए HTTP प्रतिक्रिया शीर्षलेख नीचे दिखाया गया है। मैं विशेष प्रसंस्करण इस प्रतिक्रिया को संभालने के लिए की जरूरत है, तो पता नहीं है:

HTTP/1.1 200 OK सर्वर:
अपाचे-कोयोट/1.1 Pragma: निजी
कैश-नियंत्रण: होगा दोबारा सत्यापित
समय-सीमा समाप्त : मंगलवार, 31 दिसंबर 1 99 7 23:59:59 GMT
सामग्री-विस्थापन: इनलाइन;
फ़ाइल नाम = "files.zip";
सामग्री प्रकार: आवेदन/ज़िप
स्थानांतरण-एन्कोडिंग: chunked

उत्तर

10

f.read() जरूरी पूरी फ़ाइल, लेकिन सिर्फ इसके बारे में एक पैकेट (यह छोटे अगर जो पूरी फ़ाइल हो सकता है, नहीं पढ़ है, लेकिन एक बड़ी फाइल के लिए नहीं होगा)।

आप इस तरह के पैकेट से अधिक पाश की जरूरत है:

while 1: 
    packet = f.read() 
    if not packet: 
     break 
    localFile.write(packet) 
f.close() 

f.read() एक खाली पैकेट रिटर्न दर्शाता है कि आप पूरी फ़ाइल पढ़ा है।

+2

मैं कहाँ दस्तावेज में उत्सुक होगा आप यह –

+0

पाया गया http://docs.python.org/library/urllib.html#urllib.urlopen: "फ़ाइल जैसी वस्तु वापस आती है" तो http://docs.python.org/library/stdtypes.html#file .read – RichieHindle

+0

वास्तव में सिर्फ एक पैकेट? मैंने दिखाए गए लिंक पर दस्तावेज़ों की जांच की और कहीं भी यह नहीं देखा कि यह पढ़ता है() ईओएफ तक पढ़ता नहीं है। क्या आप और अधिक व्याख्या कर सकते हैं? –

1

आप स्मृति के लिए पूरे ज़िप फ़ाइल को पढ़ने से परहेज नहीं करते हैं, तो सबसे तेज़ तरीका है पढ़ने और लिखने में यह इस प्रकार है करने के लिए:

data = f.readlines() 
with open(localFile,'wb') as output: 
    output.writelines(data) 

अन्यथा, पढ़ सकते हैं और मात्रा में लिखने के रूप में आप उन्हें प्राप्त करने के लिए नेटवर्क पर,

with open(localFile, "wb") as output: 
    chunk = f.read() 
    while chunk: 
     output.write(chunk) 
     chunk = f.read() 

यह थोड़ा कम साफ है, लेकिन पूरी फ़ाइल को स्मृति में एक साथ रखने से बचाता है। आशा करता हूँ की ये काम करेगा।

0

इस प्रयास करें:

#download file 
f = o.open(remoteFileUrl) 

response = "" 
while 1: 
    data = f.read() 
    if not data: 
     break 
    response += data 

with open(localFile, "wb") as local_file: 
    local_file.write(response) 
1

यहाँ एक और अधिक मजबूत समाधान मात्रा में फ़ाइल डाउनलोड करें और डाउनलोड की स्थिति मुद्रित करने के लिए urllib2 उपयोग कर रहा है

import os 
import urllib2 
import math 

def downloadChunks(url): 
    """Helper to download large files 
     the only arg is a url 
     this file will go to a temp directory 
     the file will also be downloaded 
     in chunks and print out how much remains 
    """ 

    baseFile = os.path.basename(url) 

    #move the file to a more uniq path 
    os.umask(0002) 
    temp_path = "/tmp/" 
    try: 
     file = os.path.join(temp_path,baseFile) 

     req = urllib2.urlopen(url) 
     total_size = int(req.info().getheader('Content-Length').strip()) 
     downloaded = 0 
     CHUNK = 256 * 10240 
     with open(file, 'wb') as fp: 
      while True: 
       chunk = req.read(CHUNK) 
       downloaded += len(chunk) 
       print math.floor((downloaded/total_size) * 100) 
       if not chunk: break 
       fp.write(chunk) 
    except urllib2.HTTPError, e: 
     print "HTTP Error:",e.code , url 
     return False 
    except urllib2.URLError, e: 
     print "URL Error:",e.reason , url 
     return False 

    return file 
+0

यह केवल तभी मजबूत होगा जब आप उस मामले को संभाल लें जहां कोई 'सामग्री-लेनघाट' हेडर भेजा नहीं गया है IMO –

+0

अच्छा बिंदु जेवियर – Gourneau

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