2016-12-12 31 views
2

私はスクリプトを使用してファイルのグループをダウンロードしています。私はこれを正常に完了し、それはまともに働いています。今、私はダウンロードの進行の動的なプリントアウトを追加しようとしました。ConnectionResetError:リモートホストによって既存の接続が強制的にクローズされました

5MBなどの小規模なダウンロード(途中で.mp4ファイル)の場合、プログレッションがうまく機能し、ファイルが正常に閉じられ、ダウンロードされた.mp4ファイルが完全にダウンロードされます。例えば上で250メガバイトとのような大きなファイルの場合は、それが正常に動作しません、私は次のエラーを取得する:

enter image description here

そしてここでは、私のコードです:

import urllib.request 
import shutil 
import os 
import sys 
import io 

script_dir = os.path.dirname('C:/Users/Kenny/Desktop/') 
rel_path = 'stupid_folder/video.mp4' 
abs_file_path = os.path.join(script_dir, rel_path) 
url = 'https://archive.org/download/SF145/SF145_512kb.mp4' 
# Download the file from `url` and save it locally under `file_name`: 

with urllib.request.urlopen(url) as response, open(abs_file_path, 'wb') as out_file: 

    eventID = 123456 

    resp = urllib.request.urlopen(url) 
    length = resp.getheader('content-length') 
    if length: 
     length = int(length) 
     blocksize = max(4096, length//100) 
    else: 
     blocksize = 1000000 # just made something up 

    # print(length, blocksize) 

    buf = io.BytesIO() 
    size = 0 
    while True: 
     buf1 = resp.read(blocksize) 
     if not buf1: 
      break 
     buf.write(buf1) 
     size += len(buf1) 
     if length: 
      print('\r[{:.1f}%] Downloading: {}'.format(size/length*100, eventID), end='')#print('\rDownloading: {:.1f}%'.format(size/length*100), end='') 
    print() 

    shutil.copyfileobj(response, out_file) 

これは小さなファイルで完璧に動作し、大きなものはエラーが出ます。私は進行インジケータコードをコメントアウトした場合さて、私は大きなファイルで、しかし、エラーを取得しない:

with urllib.request.urlopen(url) as response, open(abs_file_path, 'wb') as out_file: 

    # eventID = 123456 
    # 
    # resp = urllib.request.urlopen(url) 
    # length = resp.getheader('content-length') 
    # if length: 
    #  length = int(length) 
    #  blocksize = max(4096, length//100) 
    # else: 
    #  blocksize = 1000000 # just made something up 
    # 
    # # print(length, blocksize) 
    # 
    # buf = io.BytesIO() 
    # size = 0 
    # while True: 
    #  buf1 = resp.read(blocksize) 
    #  if not buf1: 
    #   break 
    #  buf.write(buf1) 
    #  size += len(buf1) 
    #  if length: 
    #   print('\r[{:.1f}%] Downloading: {}'.format(size/length*100, eventID), end='')#print('\rDownloading: {:.1f}%'.format(size/length*100), end='') 
    # print() 

    shutil.copyfileobj(response, out_file) 

誰がどんな考えを持っていますか?これは私のプロジェクトの最後の部分であり、私は本当に進歩を見たいと思っています。もう一度、これはPython 3.5です。何か助けてくれてありがとう!

+0

に書き込みを私は理解していない:あなたはresp' 'からと' response'から読みますか?何のために? 'buf'に完全に書き込んだら、完了したようです。または私は間違っていますか? 'out_file' BTWに直接書くことができます。 –

+0

すべての正直なところ、私は何をしているのか分かりません。しかし、私が 'shutil.copyfileobj(response、out_file)'を含まなければ、ダウンロードされたファイルは0バイトのままです。 – Kenny

+0

あなたのループで 'buf.write(buf1)'の代わりに 'out_file.write(buf1)'を試してみてください。 'io.BytesIO'オブジェクトは必要ありません。 –

答えて

1

あなたはURLを2度開いています.1度はresponse、1度はrespとなっています。あなたのプログレスバーのものでは、データを消費しているので、copyfileobjを使ってファイルをコピーすると、データは空になります(小さなファイルでは正しくないかもしれませんが、プログレスバーと有効なファイルを取得するには、あなたの問題のorgin)

は、次の操作を行います。あなたのコードに行わ

with urllib.request.urlopen(url) as response, open(abs_file_path, 'wb') as out_file: 

    eventID = 123456 

    length = response.getheader('content-length') 
    if length: 
     length = int(length) 
     blocksize = max(4096, length//100) 
    else: 
     blocksize = 1000000 # just made something up 


    size = 0 
    while True: 
     buf1 = response.read(blocksize) 
     if not buf1: 
      break 
     out_file.write(buf1) 
     size += len(buf1) 
     if length: 
      print('\r[{:.1f}%] Downloading: {}'.format(size/length*100, eventID), end='')#print('\rDownloading: {:.1f}%'.format(size/length*100), end='') 
    print() 

簡略化:responseとして

  • 一つだけurlopen
  • なしBytesIO、直接out_file
+0

私はrespとレスポンスによってあなたが今何を意味するかを見て、大いに助けてくれてありがとう! – Kenny

関連する問題