2012-04-24 13 views
2

zip 파일을 반환하는 URL이 여러 개 있습니다. 대부분의 파일, 나는 다음과 같이 urllib2가 라이브러리를 사용하여 다운로드 할 수 있어요 :파이썬으로 큰 zip 파일 다운로드

request = urllib2.urlopen(url) 
zip_file = request.read() 

제가하는 데 문제는 파일 중 하나의 크기가 35 메가 바이트 (압축)이며, 내가 할 수 적이 있어요 없다는 것입니다 이 라이브러리를 사용하여 다운로드를 마칩니다. wget과 브라우저를 사용하여 정상적으로 다운로드 할 수 있습니다. 나는이 같은 chuncks에서 파일을 다운로드 시도

:

request = urllib2.urlopen(url) 
buffers = [] 
while True: 
    buffer = request.read(8192) 
    if buffer: 
     buffers.append(buffer) 
    else: 
     break 
final_file = ''.join(buffers) 

그러나이 또한 다운로드를 완료하지 않습니다. 오류가 발생하지 않으므로 디버깅하기가 어렵습니다. 불행히도 url/file 예제를 게시 할 수 없습니다.

의견이나 제안이 있으십니까?

+0

더 많은 정보 나 URL을 재생산하지 않으면 디버깅하기가 매우 어렵습니다. 그러나, 왜'final_file = request.read()'를 사용하지 않을까요? 위의 코드는 모든 데이터를 메모리에 저장하는 문자열 배열을 작성하므로 한 번에 코드를 읽는 코드를 복잡하게 만들지 않습니다. –

+0

[urllib2를 사용하여 python으로 zip 파일을 다운로드하려면 어떻게합니까?] (http://stackoverflow.com/questions/4028697/how-do-i-download-a-zip-file-in-python-using) -urllib2) –

+0

@benhoyt 이것은 첫 번째 시도이지만 작동하지 않았습니다. 그래서 chuncks에있는 파일을 분할하려고 시도했습니다. – duduklein

답변

2

내 응용 프로그램에서 복사/붙여 넣기하여 자신의 업데이트 설치 프로그램을 다운로드합니다. 블록 단위로 파일을 읽고 즉시 블록을 디스크의 출력 파일에 저장합니다.

def DownloadThreadFunc(self): 
    try: 
     url = self.lines[1] 
     data = None 
     req = urllib2.Request(url, data, {}) 
     handle = urllib2.urlopen(req) 

     self.size = int(handle.info()["Content-Length"]) 
     self.actualSize = 0 
     name = path.join(DIR_UPDATES, url.split("/")[-1]) 
     blocksize = 64*1024 

     fo = open(name, "wb") 
     while not self.terminate: 
      block = handle.read(blocksize) 
      self.actualSize += len(block) 
      if len(block) == 0: 
       break 
      fo.write(block) 
     fo.close() 
    except (urllib2.URLError, socket.timeout), e: 
     try: 
      fo.close() 
     except: 
      pass 
     error("Download failed.", unicode(e)) 

내가 필요하면 GUI 버튼에서 다운로드를 취소하는 GUI 스레드와 self.terminate의 다운로드 진행 상황을 보여 self.sizeself.actualSize를 사용합니다.

+0

이것은 완벽하게 작동했습니다! 고마워. 하지만 내 단순화 된 버전이 작동하지 않는 이유를 말해 줄 수 있습니까? – duduklein

+0

잘 모르겠다. 그러나 나는 이런 구조가 의심 스럽다.'if buffer :'. 블록을 디스크에 직접 저장하여 출력 파일에서도 진행 상황을 확인할 수 있습니다. – Fenikso

+0

귀하의 요지를 봅니다. 나는 코드의 버전을 메모리에만 저장하려고 시도했지만 잘 작동했다. 그것은 내 초기 버퍼 크기 (너무 작음) 일 수 있습니까? – duduklein

관련 문제