代码之家  ›  专栏  ›  技术社区  ›  speedplane

python urllib2进程挂钩

  •  28
  • speedplane  · 技术社区  · 15 年前

    我正在尝试使用URLLIB2HTTP客户机在Python中创建下载进度条。我已经浏览了API(和Google),看起来Urllib2不允许您注册进度挂钩。但是,旧的不推荐使用的urllib确实具有此功能。

    有人知道如何使用urllib2创建进度条或报告挂钩吗?还是有其他黑客可以获得类似的功能?

    4 回复  |  直到 10 年前
        1
  •  41
  •   Kenan Banks    15 年前

    这里有一个完全有效的例子,它建立在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)
    
        2
  •  12
  •   Anurag Uniyal    15 年前

    为什么不直接成批地读取数据,并在其间做你想做的任何事情,例如在线程中运行、钩住一个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.
    
        3
  •  5
  •   joshk0    13 年前

    urlgrabber 已内置对进度通知的支持。

        4
  •  1
  •   user4459011    10 年前

    简化版本:

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