其他提示

如果你只想要文件名本身,假设最后没有查询变量,如 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或文件路径的最后部分。

我认为“文件名”是指在http传输方面,它不是一个非常明确的概念。服务器可以(但不是必须)提供一个作为“content-disposition”的服务器。标题,您可以尝试使用 remotefile.headers ['Content-Disposition'] 来获取它。如果失败,您可能必须自己解析URI。

刚看到这个我通常做..

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

使用 urlsplit 是最安全的选择:

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

你的意思是 urllib2.urlopen urllib2 模块中没有名为 openfile 的函数。

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

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

瞧。

您还可以将两个评分最高的答案结合起来: 使用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)

os.path.basename 函数不仅适用于文件路径,也适用于网址,因此您无需亲自手动解析URL。另外,请务必注意,您应该使用 result.url 而不是原始网址来跟踪重定向响应:

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

我想这取决于解析你的意思。没有解析URL就无法获取文件名,即远程服务器没有为您提供文件名。但是,您不必自己做很多事情,那就是 urlparse 模块:

In [9]: urlparse.urlparse('http://example.com/somefile.zip')
Out[9]: ('http', 'example.com', '/somefile.zip', '', '', '')

不是我所知道的。

但你可以这样简单地解析它:

<代码>

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

使用请求,但您可以使用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)

你可能在这里使用简单的正则表达式。类似的东西:

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

使用非操作系统的 PurePosixPath &#8212;依赖和优雅地处理网址是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'

注意这里没有网络流量或任何东西(即那些网址没有去任何地方) - 只是使用标准的解析规则。

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,但可能仍有帮助:)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top