urllib2 文件名

urllib2 file name

提问人:defrex 提问时间:10/2/2008 最后编辑:Adam Nelsondefrex 更新时间:6/27/2016 访问量:40057

问:

如果我使用 urllib2 打开一个文件,如下所示:

remotefile = urllib2.urlopen('http://example.com/somefile.zip')

除了解析原始 URL 之外,有没有一种简单的方法可以获取文件名?

编辑:将 openfile 更改为 urlopen...不知道这是怎么发生的。

编辑2:我最终使用了:

filename = url.split('/')[-1].split('#')[0].split('?')[0]

除非我弄错了,否则这也应该去除所有潜在的查询。

python 网址 urllib2

评论

0赞 user15453 10/2/2008
我认为这不合适。我的意思是urllib2.openfile(...
0赞 nealmcb 2/9/2012
请确保您知道在这两种情况下您想要什么:尾部斜杠 () 和无路径:您的示例肯定会在后者上失败(返回“example.com”)。@insin的最终答案也是如此。这就是为什么使用 urlsplit 是好建议的另一个原因。http://example.com/somefile/http://example.com
0赞 jozxyqk 11/1/2015
从响应标头:stackoverflow.com/questions/11783269/...
0赞 ʇsәɹoɈ 10/12/2016
这里的许多答案都忽略了一个事实,即有两个地方可以查找文件名:URL 和 Content-Disposition 标头字段。当前所有提到标头的答案都忽略了 cgi.parse_header() 将正确解析它。这里有一个更好的答案:stackoverflow.com/a/11783319/205212

答:

2赞 Dan Lenski 10/2/2008 #1

你是说 ?模块中没有调用任何函数。urllib2.urlopenopenfileurllib2

无论如何,请使用以下函数:urllib2.urlparse

>>> from urllib2 import urlparse
>>> print urlparse.urlsplit('http://example.com/somefile.zip')
('http', 'example.com', '/somefile.zip', '', '')

瞧。

7赞 Rafał Dowgird 10/2/2008 #2

我认为当涉及到 http 传输时,“文件名”并不是一个定义良好的概念。服务器可能(但不是必需的)提供一个作为“content-disposition”标头,您可以尝试使用 .如果此操作失败,则可能需要自行分析 URI。remotefile.headers['Content-Disposition']

49赞 Jonny Buchanan 10/2/2008 #3

你的意思是urllib2.urlopen吗?

如果服务器通过检查发送 Content-Disposition 标头,您可能会提升预期的文件名,但我认为您只需要解析 url。remotefile.info()['Content-Disposition']

您可以使用 ,但是如果您有任何像第二个示例中那样的 URL,您最终将不得不自己提取文件名:urlparse.urlsplit

>>> urlparse.urlsplit('http://example.com/somefile.zip')
('http', 'example.com', '/somefile.zip', '', '')
>>> urlparse.urlsplit('http://example.com/somedir/somefile.zip')
('http', 'example.com', '/somedir/somefile.zip', '', '')

不妨这样做:

>>> 'http://example.com/somefile.zip'.split('/')[-1]
'somefile.zip'
>>> 'http://example.com/somedir/somefile.zip'.split('/')[-1]
'somefile.zip'

评论

7赞 Thomas Wouters 10/2/2008
使用 posixpath.basename() 而不是手动拆分 '/'。
8赞 Dan Lenski 10/2/2008
我总是使用 urlsplit() 并且从不直接拆分字符串。如果您的 URL 附加了片段或查询,后者会窒息,比如说 example.com/filename.html?cookie=55#Section_3
0赞 awiebe 7/7/2017
转义角色呢?这些应该先解码吗?
1赞 miracle2k 10/2/2008 #4

我想这取决于你所说的解析是什么意思。如果不解析 URL,就无法获取文件名,即远程服务器不会为您提供文件名。但是,您不必自己做太多事情,这里有一个模块:urlparse

In [9]: urlparse.urlparse('http://example.com/somefile.zip')
Out[9]: ('http', 'example.com', '/somefile.zip', '', '', '')
0赞 user15453 10/2/2008 #5
import os,urllib2
resp = urllib2.urlopen('http://www.example.com/index.html')
my_url = resp.geturl()

os.path.split(my_url)[1]

# 'index.html'

这不是 openfile,但也许仍然有助于:)

1赞 Corey Goldberg 10/2/2008 #6

我不知道。

但是你可以像这样轻松地解析它:

url = 'http://example.com/somefile.zip'
print url.split('/')[-1]

13赞 Jay 10/3/2008 #7

如果你只想要文件名本身,假设末尾没有像 http://example.com/somedir/somefile.zip?foo=bar 这样的查询变量,那么你可以使用 os.path.basename:

[user@host]$ python
Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04) 
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.path.basename("http://example.com/somefile.zip")
'somefile.zip'
>>> os.path.basename("http://example.com/somedir/somefile.zip")
'somefile.zip'
>>> os.path.basename("http://example.com/somedir/somefile.zip?foo=bar")
'somefile.zip?foo=bar'

其他一些发帖者提到使用 urlparse,这将起作用,但您仍然需要从文件名中删除前导目录。如果您使用 os.path.basename(),则不必担心这一点,因为它仅返回 URL 或文件路径的最后一部分。

评论

3赞 Rafał Dowgird 6/11/2013
用于解析 URL 似乎依赖于当前的操作系统拆分路径,就像拆分 URL 一样。我不认为它对每个操作系统都有保证。os.path
1赞 j08lue 1/12/2017
这在 Windows 上不起作用。请改用。import posixpath; posixpath.basename
4赞 Filipe Correia 4/1/2013 #8

使用是最安全的选择:urlsplit

url = 'http://example.com/somefile.zip'
urlparse.urlsplit(url).path.split('/')[-1]
0赞 DoomedRaven 2/27/2014 #9

使用请求,但你可以用 urllib(2) 轻松完成

import requests
from urllib import unquote
from urlparse import urlparse

sample = requests.get(url)

if sample.status_code == 200:
    #has_key not work here, and this help avoid problem with names

    if filename == False:

        if 'content-disposition' in sample.headers.keys():
            filename = sample.headers['content-disposition'].split('filename=')[-1].replace('"','').replace(';','')

        else:

            filename = urlparse(sample.url).query.split('/')[-1].split('=')[-1].split('&')[-1]

            if not filename:

                if url.split('/')[-1] != '':
                    filename = sample.url.split('/')[-1].split('=')[-1].split('&')[-1]
                    filename = unquote(filename)
6赞 TMF Wolfman 3/21/2015 #10

刚看到这个我通常做..

filename = url.split("?")[0].split("/")[-1]
2赞 Régis B. 5/11/2015 #11

该函数不仅适用于文件路径,也适用于网址,因此您不必自己手动解析网址。此外,请务必注意,您应该使用原始 url 代替原始 url 来跟踪重定向响应:os.path.basenameresult.url

import os
import urllib2
result = urllib2.urlopen(url)
real_url = urllib2.urlparse.urlparse(result.url)
filename = os.path.basename(real_url.path)
0赞 Vovan Kuznetsov 9/11/2015 #12

您可以在此处使用简单的正则表达式。像这样:

In [26]: import re
In [27]: pat = re.compile('.+[\/\?#=]([\w-]+\.[\w-]+(?:\.[\w-]+)?$)')
In [28]: test_set 

['http://www.google.com/a341.tar.gz',
 'http://www.google.com/a341.gz',
 'http://www.google.com/asdasd/aadssd.gz',
 'http://www.google.com/asdasd?aadssd.gz',
 'http://www.google.com/asdasd#blah.gz',
 'http://www.google.com/asdasd?filename=xxxbl.gz']

In [30]: for url in test_set:
   ....:     match = pat.match(url)
   ....:     if match and match.groups():
   ....:         print(match.groups()[0])
   ....:         

a341.tar.gz
a341.gz
aadssd.gz
aadssd.gz
blah.gz
xxxbl.gz
0赞 Adam Nelson 4/12/2016 #13

使用 PurePosixPath,它不是依赖于操作系统并优雅地处理 url 是 pythonic 解决方案:

>>> from pathlib import PurePosixPath
>>> path = PurePosixPath('http://example.com/somefile.zip')
>>> path.name
'somefile.zip'
>>> path = PurePosixPath('http://example.com/nested/somefile.zip')
>>> path.name
'somefile.zip'

请注意,这里没有网络流量或任何东西(即这些 url 不会去任何地方)——只是使用标准解析规则。

2赞 Yth 4/28/2016 #14

您也可以将两个评分最高的答案结合起来: 使用 urllib2.urlparse.urlsplit() 获取 URL 的路径部分,然后使用 os.path.basename 获取实际文件名。

完整的代码是:

>>> remotefile=urllib2.urlopen(url)
>>> try:
>>>   filename=remotefile.info()['Content-Disposition']
>>> except KeyError:
>>>   filename=os.path.basename(urllib2.urlparse.urlsplit(url).path)