2014-02-14 42 views
2

如果下载的数据是gzip的编码,内容长度和数据的总长度在for data in response.iter_content():加入他们后,我有在Python progress bar and downloadsPython3进度条和用gzip

陈述的答案有点问题下载是不同的,因为在它是更大的原因自动解压缩gzip编码应答

所以杆越来越长,一旦成为长为单个线,就开始淹没的终端

一个工作示例问题(该网站是我在google上发现的第一个网站帽子有两个内容长度和gzip编码):

import requests,sys 

def test(link): 
    print("starting") 
    response = requests.get(link, stream=True) 
    total_length = response.headers.get('content-length') 
    if total_length is None: # no content length header 
     data = response.content 
    else: 
     dl = 0 
     data = b"" 
     total_length = int(total_length) 
     for byte in response.iter_content(): 
      dl += len(byte) 
      data += (byte) 
      done = int(50 * dl/total_length) 
      sys.stdout.write("\r[%s%s]" % ('=' * done, ' ' * (50-done))) 
      sys.stdout.flush() 
    print("total data size: %s, content length: %s" % (len(data),total_length)) 

test("http://www.pontikis.net/") 

ps的,我是在Linux,但它应该影响其他操作系统太(除Windows引起\ R没有它IIRC工作)

和我使用的cookies(和gzip)处理因此与urllib而其他模块的解决方案requests.Session是不是我期待的

+0

如果你的问题是请求自动解压缩数据,你可能不应该使用请求。由于您没有进行任何身份验证,因此标准的urllib.request应该可能没问题。然后,您可以使用工作进度条检索数据,并在文件完全下载时使用zlib模块将其解压缩。 – Kritzefitz

+0

我需要在登录后使用发布请求来坚持cookie,因为我正在做什么这就是为什么我说request.session,也是为什么我说urllib的解决方案不是我在找什么 –

+0

哦,对不起。最后没有看到。 – Kritzefitz

回答

0

也许你应该尝试禁用gzip压缩或以其他方式占了。

的方式将其关闭的请求(使用会话时,你说你是):

import requests 

s = requests.Session() 
del s.headers['Accept-Encoding'] 

发送现将标题:Accept-Encoding: Identity和服务器不应该尝试使用gzip压缩。如果您尝试下载gzip编码文件,则不应该遇到此问题。您将收到application/x-gzip-compressedContent-Type。如果网站gzip压缩,您会收到的text/html例如Content-Typegzip一个Content-Encoding

如果服务器始终提供压缩的内容,那么你的运气,但没有服务器应该这样做。


如果你想要做的事与请求的功能API:

import requests 

r = requests.get('url', headers={'Accept-Encoding': None}) 

通过功能API的报头值设置为None(甚至到session.get通话)去除该头请求。

+0

这会解决问题,但它会使它成为一个更大的瓶颈,不仅如此,我不认为你可以在一个正常的requests.get上使用del,删除那个头文件 –

+0

@freeforalltousez,除非你下载了几个技嘉长的网页,这应该不会造成太大的麻烦。此外,你问了如何在会话中做到这一点,但我已经更新了我的答案,即如何在'requests.get'上做同样的事情。如果您的问题不再符合您的要求,请更新它。 –

+0

我想我现在会标记这个答案,直到另一个更好的人出现 –

0

你可以替换...

dl += len(byte)

...有:

dl = response.raw.tell()

documentation

告诉():获取数到目前为止,已经通过线缆的字节数。甲基:可从 通过返回的内容的量不同HTTPResponse.read 如果字节在电线上(例如,压缩)编码。