使用Python urllib如何设置文件下载超时?

19

我是Python初学者。如果下载视频文件的进程超过500秒,我希望能够设置超时时间。

import urllib
try:
   urllib.urlretrieve ("http://www.videoURL.mp4", "filename.mp4")
except Exception as e:
   print("error")

我该如何修改代码才能实现这一点?


可能是 https://dev59.com/2nRB5IYBdhLWcg3wgXdV 的重复问题,该问题涉及Python下载时如何优雅地超时处理。 - Robert Horvick
3个回答

16
更好的方法是使用requests,这样您就可以流式传输结果并轻松检查超时:
import requests

# Make the actual request, set the timeout for no data to 10 seconds and enable streaming responses so we don't have to keep the large files in memory
request = requests.get('http://www.videoURL.mp4', timeout=10, stream=True)

# Open the output file and make sure we write in binary mode
with open('filename.mp4', 'wb') as fh:
    # Walk through the request response in chunks of 1024 * 1024 bytes, so 1MiB
    for chunk in request.iter_content(1024 * 1024):
        # Write the chunk to the file
        fh.write(chunk)
        # Optionally we can check here if the download is taking too long

10

尽管urlretrieve没有这个功能,但您仍然可以为所有新的套接字对象设置默认超时时间(以秒为单位)。

import socket
import urllib    

socket.setdefaulttimeout(15)

try:
   urllib.urlretrieve ("http://www.videoURL.mp4", "filename.mp4")
except Exception as e:
   print("error")

1

urlretrieve没有这个选项。但是你可以很容易地使用urlopen并将结果写入文件来执行你的示例,如下所示:

request = urllib.urlopen("http://www.videoURL.mp4", timeout=500)
with open("filename.mp4", 'wb') as f:
    try:
        f.write(request.read())
    except:
        print("error")

如果你正在使用Python 3,那么你应该使用urllib库。但是如果你正在使用Python 2,你应该使用urllib2库。


1
urlopen 可以很容易地打开文件,但对于大文件而言,request.read() 可能会变得缓慢并且需要很长时间。你应该考虑在该函数周围添加一个超时,可能使用 signal 包。 - fanchyna
不仅可能会很慢,而且可能完全失败。例如,假设文件大小为10GB,无法放入内存中。 - LarsH
请注意,Python 3 中的 urllib.request.urlopen() 函数等同于 urllib2.urlopen(),而 urllib.urlopen() 已被删除。在 3.6 版本中,正确的调用方式是 urllib.request.urlopen()。我不知道是否有 Python 版本可用 urllib.urlopen(),因此我不会编辑答案。 - Andreas Haferburg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接