29

urllib2 httpクライアントを使用して、Pythonでダウンロードプログレスバーを作成しようとしています。API(およびGoogle)を調べましたが、urllib2では進行状況フックを登録できないようです。ただし、古い非推奨のurllibにはこの機能があります。

urllib2を使用してプログレスバーまたはレポートフックを作成する方法を知っている人はいますか?または、同様の機能を取得するための他のハックはありますか?

4

5 に答える 5

42

これは、Anurag の応答のチャンク化のアプローチに基づいて構築された、完全に機能する例です。私のバージョンでは、チャンク サイズを設定し、任意のレポート機能を追加できます。

import urllib2, sys

def chunk_report(bytes_so_far, chunk_size, total_size):
   percent = float(bytes_so_far) / total_size
   percent = round(percent*100, 2)
   sys.stdout.write("Downloaded %d of %d bytes (%0.2f%%)\r" % 
       (bytes_so_far, total_size, percent))

   if bytes_so_far >= total_size:
      sys.stdout.write('\n')

def chunk_read(response, chunk_size=8192, report_hook=None):
   total_size = response.info().getheader('Content-Length').strip()
   total_size = int(total_size)
   bytes_so_far = 0

   while 1:
      chunk = response.read(chunk_size)
      bytes_so_far += len(chunk)

      if not chunk:
         break

      if report_hook:
         report_hook(bytes_so_far, chunk_size, total_size)

   return bytes_so_far

if __name__ == '__main__':
   response = urllib2.urlopen('http://www.ebay.com');
   chunk_read(response, report_hook=chunk_report)
于 2010-01-08T19:11:23.317 に答える
12

チャンクでデータを読み取り、その間にやりたいことを何でもしてみませんか。たとえば、スレッドで実行したり、UI にフックしたりなどです。

import urllib2

urlfile = urllib2.urlopen("http://www.google.com")

data_list = []
chunk = 4096
while 1:
    data = urlfile.read(chunk)
    if not data:
        print "done."
        break
    data_list.append(data)
    print "Read %s bytes"%len(data)

出力:

Read 4096 bytes
Read 3113 bytes
done.
于 2010-01-08T15:48:04.240 に答える
5

urlgrabberには、進行状況通知のサポートが組み込まれています。

于 2010-01-08T15:53:02.397 に答える
1

簡易版:

temp_filename = "/tmp/" + file_url.split('/')[-1]
f = open(temp_filename, 'wb')
remote_file = urllib2.urlopen(file_url)

try:
    total_size = remote_file.info().getheader('Content-Length').strip()
    header = True
except AttributeError:
    header = False # a response doesn't always include the "Content-Length" header

if header:
    total_size = int(total_size)

bytes_so_far = 0

while True:
    buffer = remote_file.read(8192)
    if not buffer:
        sys.stdout.write('\n')
        break

    bytes_so_far += len(buffer)
    f.write(buffer)
    if not header:
        total_size = bytes_so_far # unknown size

    percent = float(bytes_so_far) / total_size
    percent = round(percent*100, 2)
    sys.stdout.write("Downloaded %d of %d bytes (%0.2f%%)\r" % (bytes_so_far, total_size, percent))
于 2015-01-15T19:22:18.650 に答える