【问题标题】:What command to use instead of urllib.request.urlretrieve?用什么命令代替 urllib.request.urlretrieve?
【发布时间】:2013-02-08 17:12:15
【问题描述】:

我目前正在编写一个从 URL 下载文件的脚本

import urllib.request
urllib.request.urlretrieve(my_url, 'my_filename')

文档urllib.request.urlretrieve 状态:

以下函数和类是从 Python 2 模块 urllib(相对于 urllib2)移植而来的。它们可能会在将来的某个时候被弃用。

因此我想避免它,这样我就不必在不久的将来重写这段代码。

我无法在标准库中找到像 download(url, filename) 这样的另一个接口。如果urlretrieve 被认为是 Python 3 中的遗留接口,那么替代的接口是什么?

【问题讨论】:

    标签: python python-3.x python-requests urllib


    【解决方案1】:

    requests 非常适合这个。虽然安装它有一些依赖项。这是一个例子。

    import requests
    r = requests.get('imgurl')
    with open('pic.jpg','wb') as f:
      f.write(r.content)
    

    【讨论】:

    • 这不是将响应存储在内存中吗?是否有替代 urlretrieve 流到磁盘的请求?
    • @KyleBarron:是的,看起来是这样。我想使用requests 库正确模拟urlretrireve,需要使用here 所示的流。
    【解决方案2】:

    已弃用是一回事,将来可能会被弃用是另一回事。

    如果它符合您的需求,我会继续使用urlretrieve

    也就是说,你可以不用它:

    from urllib.request import urlopen
    from shutil import copyfileobj
    
    with urlopen(my_url) as in_stream, open('my_filename', 'wb') as out_file:
        copyfileobj(in_stream, out_file)
    

    【讨论】:

    • 非常感谢。我不知道shutil图书馆甚至存在:)
    • 哇,效果很好。我一直在寻找同样的东西,但是对于小片段的音频,并且无法弄清楚如何将其保存到文件中。有一阵子没找到urlretrieve,没想到urlopen会给我字节——我想我应该找一个可以保存文件的方法,而不是进入文件读取/保存位。我想这是编程的标准做法,所以它应该是有意义的,但我以前从未使用过 I/O。谢谢,这比我想象的要简单得多。
    • 感谢 copyfileobj! urlretrieve 的问题在于它无法确定服务器故障(502/404/whatever)。
    • 我正在使用urlretrieve(..) 中的reporthook 来更新进度条,但urlopen(..) 中不存在该参数。如果切换到urlopen(..),如何定期更新进度条?
    • @y0prst:“没办法”是错误的。如果服务器出现故障,你会得到一个异常:如果你直接使用urlopen(),你会得到完全相同的异常(HTTPError)——这并不奇怪:urlretrieve() is a just convenience wrapper around urlopen():如果它适合你,就不需要自己重新实现。
    【解决方案3】:

    不使用shutil 的另一种解决方案,也没有像requests 这样的其他外部库。

    import urllib.request
    
    image_url = "https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon.png"
    response = urllib.request.urlopen(image_url)
    image = response.read()
    
    with open("image.png", "wb") as file:
        file.write(image)
    

    【讨论】:

    • 您好,欢迎来到 SO。仅代码的答案通常被认为不太有用。请编辑您的答案以添加一些上下文并解释您的解决方案。
    【解决方案4】:

    不确定这是否是您正在寻找的,或者是否有“更好”的方式,但这是我在库之后添加到脚本顶部的内容,以使我的脚本与 Python 2/3 兼容.

    # Python version compatibility
    if version.major == 3:
        from urllib.error import HTTPError
        from urllib.request import urlopen, urlretrieve
    
    elif version.major == 2:
        from urllib2 import HTTPError, urlopen
    
        def urlretrieve(url, data):
            url_data = urlopen(url)
            with open(data, "wb") as local_file:
                local_file.write(url_data.read())
    else:
        raise ValueError('No valid Python interpreter found.')
    

    这至少看起来像是一个方便的技巧,我希望这可能对某人有所帮助。

    最好的!

    【讨论】:

      猜你喜欢
      • 2017-08-07
      • 1970-01-01
      • 2022-07-17
      • 1970-01-01
      • 2014-05-22
      • 1970-01-01
      • 2013-03-14
      • 1970-01-01
      • 2011-10-08
      相关资源
      最近更新 更多