在Python中使用urllib2。如何获取我正在下载的文件的名称?

时间:2011-04-04 02:00:10

标签: python download default filenames urllib2

我是一名蟒蛇初学者。我正在使用urllib2下载文件。当我下载文件时,我指定了一个文件名,用于将下载的文件保存到我的硬盘上。但是,如果我使用浏览器下载文件,则会自动提供默认文件名。

以下是我的代码的简化版本:

def downloadmp3(url):
    webFile = urllib2.urlopen(url)
    filename = 'temp.zip'
    localFile = open(filename, 'w')
    localFile.write(webFile.read())

该文件下载得很好,但是如果我将存储在变量“url”中的字符串输入到我的浏览器中,则在下载时会给文件指定一个默认文件名。我想将这个文件名用于我下载的文件而不是'temp.zip'或我指定的任何文件。

如何使用urllib2(或其他一些Python库)来保存文件,其中包含我正在下载的服务器所需的文件名?

如果有人不理解这个问题,请说出来,以便我可以尝试让它更清楚。

4 个答案:

答案 0 :(得分:7)

服务器通常通过content-disposition标头包含文件名:

content-disposition: attachment; filename=foo.pdf

您可以通过

访问标题
result = urllib2.urlopen(...)
result.info() <- contains the headers


i>>> import urllib2
ur>>> result = urllib2.urlopen('http://zopyx.com')
>>> print result
<addinfourl at 4302289808 whose fp = <socket._fileobject object at 0x1006dd5d0>>
>>> result.info()
<httplib.HTTPMessage instance at 0x1006fbab8>
>>> result.info().headers
['Date: Mon, 04 Apr 2011 02:08:28 GMT\r\n', 'Server: Zope/(unreleased version, python 2.4.6, linux2) ZServer/1.1 Plone/3.3.4\r\n', 'Content-Length: 15321\r\n', 'Content-Type: text/html; charset=utf-8\r\n', 'Via: 1.1 www.zopyx.com\r\n', 'Cache-Control: max-age=3600\r\n', 'Expires: Mon, 04 Apr 2011 03:08:28 GMT\r\n', 'Connection: close\r\n']

http://docs.python.org/library/urllib2.html

但请注意,此标头不需要存在。否则,您需要自己从请求的URL生成合理的名称 - 例如来自URI的最后一个组件。 在这种情况下使用Python的urlparse()方法。

答案 1 :(得分:1)

我之前回答的问题是他们使用的是原始网址,如果是重定向,则会失败。我是这样做的:(注意使用result.url代替url

import os
import urllib2
result = urllib2.urlopen(url)
filename = os.path.basename(urllib2.urlparse.urlparse(result.url).path)

答案 2 :(得分:0)

你可以使用urlretrieve:

来做到这一点

http://docs.python.org/library/urllib.html

答案 3 :(得分:0)

我遇到一个问题,服务器没有给我任何content-disposition标题,所以如果它也是你的情况,你可以从url中提取文件名,如下所示:

os.path.basename(urlparse.urlparse(file_url))

就我而言,我使用了包含文件扩展名的file_stream.headers.subtype,并根据我的django模型slug重命名了文件,这是一个例子:

import urlparse, os

tmp_file = NamedTemporaryFile(delete=True)
file_stream = urllib2.urlopen(file_url)
tmp_file.write(file_stream.read())
tmp_file.flush()

new_file_name = "some_prefix_" + my_model.slug + "." + file_stream.headers.subtype
#You may prefer this:
# new_file_name = os.path.basename(urlparse.urlparse(file_url))

my_model.file.save(new_file_name, File(tmp_file))

最后一行是使用django的保存方法保存文件,也通过在末尾添加随机字符来处理重复的文件名:)

真棒。