【问题标题】:Alternative of urllib.urlretrieve in Python 3.5Python 3.5 中 urllib.urlretrieve 的替代方案
【发布时间】:2016-11-16 10:41:05
【问题描述】:

我目前正在 UDACITY 学习机器学习课程。他们在那里用 python 2.7 编写了一些代码,但是由于我目前使用的是 python 3.5,所以我遇到了一些错误。这是代码

import urllib
url = "https://www.cs.cmu.edu/~./enron/enron_mail_20150507.tgz"
urllib.urlretrieve(url, filename="../enron_mail_20150507.tgz")
print ("download complete!") 

我试过 urllib.request 。

  import urllib
  url = "https://www.cs.cmu.edu/~./enron/enron_mail_20150507.tgz"
  urllib.request(url, filename="../enron_mail_20150507.tgz")
  print ("download complete!")

但仍然给我错误。

urllib.request(url, filename="../enron_mail_20150507.tgz")
TypeError: 'module' object is not callable

我使用 PyCharm 作为我的 IDE。

【问题讨论】:

  • 如果requests 可用,我会使用它
  • 有人刚刚回答并为我工作。而不是 urllib.urlretrive 必须使用 urllib.request.urlretrieve

标签: python python-3.x urllib2


【解决方案1】:

你会使用urllib.request.urlretrieve。请注意,此功能“可能会在将来的某个时候被弃用”,因此您最好使用不太可能被弃用的接口:

# Adapted from the source:
# https://hg.python.org/cpython/file/3.5/Lib/urllib/request.py#l170
with open(filename, 'wb') as out_file:
    with contextlib.closing(urllib.request.urlopen(url)) as fp:
        block_size = 1024 * 8
        while True:
            block = fp.read(block_size)
            if not block:
                break
            out_file.write(block)

对于足够小的文件,您可以只使用readwrite 并完全放弃循环。

【讨论】:

  • 这正是我所需要的,但我的天哪,太丑了。
【解决方案2】:

您可以使用shutil.copyfileobj() 神奇地从 url 字节流复制到文件。

import urllib.request
import shutil

url = "http://www.somewebsite.com/something.pdf"
output_file = "save_this_name.pdf"
with urllib.request.urlopen(url) as response, open(output_file, 'wb') as out_file:
    shutil.copyfileobj(response, out_file)

来源:https://stackoverflow.com/a/48691447/1174102

【讨论】:

    【解决方案3】:

    我知道这个问题早已得到解答,但我会为任何未来的观众做出贡献。

    建议的解决方案很好,但主要问题是如果您使用无效的 url,它会生成空文件。

    作为解决此问题的方法,我对代码进行了调整:

    def getfile(url,filename,timeout=45):
        with contextlib.closing(urlopen(url,timeout=timeout)) as fp:
            block_size = 1024 * 8
            block = fp.read(block_size)
            if block:
                with open(filename,'wb') as out_file:
                    out_file.write(block)
                    while True:
                        block = fp.read(block_size)
                        if not block:
                            break
                        out_file.write(block)
            else:
                raise Exception ('nonexisting file or connection error')
    

    希望对你有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-05-05
      • 1970-01-01
      • 2021-04-13
      • 2011-02-09
      • 2015-06-19
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多