2016-11-14 160 views
2

我使用urllib3来爬网。示例代码:Python | HTTP - 如何在下载之前检查文件大小

from urllib3 import PoolManager 

pool = PoolManager() 
response = pool.request("GET", url) 

的问题是,我可以在URL,它是一个真正的大文件的下载,我不是在下载它interseted绊倒。

我发现这个问题 - Link - 它建议使用urlliburlopen。我不想联系服务器两次。

我想限制文件大小为25MB。 有没有办法可以做到这一点urllib3

+0

阅读直到你点击25MB,然后取消下载? – jarmod

+0

这是一个选项。我怎样才能做到这一点? –

+3

您可以使用HTTP HEAD谓词并读取Content-Length标题来检索大小。如果服务器省略了Content-Length,除非像jarmod提到的那样开始下载文件,否则无法检查大小。 –

回答

2

如果服务器提供了一个Content-Length标题,那么您可以使用它来确定是否要继续下载正文的其余部分。如果服务器没有提供标题,那么您需要传输响应,直到您决定不再继续。

要做到这一点,你需要确保你是not preloading the full response

from urllib3 import PoolManager 

pool = PoolManager() 
response = pool.request("GET", url, preload_content=False) 

# Maximum amount we want to read 
max_bytes = 1000000 

content_bytes = response.headers.get("Content-Length") 
if content_bytes and int(content_bytes) < max_bytes: 
    # Expected body is smaller than our maximum, read the whole thing 
    data = response.read() 
    # Do something with data 
    ... 
elif content_bytes is None: 
    # Alternatively, stream until we hit our limit 
    amount_read = 0 
    for chunk in r.stream(): 
     amount_read += len(chunk) 
     # Save chunk 
     ... 
     if amount_read > max_bytes: 
      break 

# Release the connection back into the pool 
response.release_conn() 
+0

我还打开了一个问题来改进我们针对此场景的文档,请添加任何有用或有用的附加注释:https://github.com/shazow/urllib3/issues/1037 – shazow

+0

快速问题:因为您不关闭连接并将其释放到池中,下一个请求是否会恢复下载并因为无法识别HTTP响应而中断?难道它不应该被强制关闭? – spectras

+0

@spectras老实说,我并不是100%确定会发生什么事情,但如果它确实无法恢复连接,那么我会认为它是urllib3中的一个错误,并要求您报告。 :)我很确定我们在重新使用连接之前进行检查。 – shazow

相关问题