提问人:defrex 提问时间:10/2/2008 最后编辑:Adam Nelsondefrex 更新时间:6/27/2016 访问量:40057
urllib2 文件名
urllib2 file name
问:
如果我使用 urllib2 打开一个文件,如下所示:
remotefile = urllib2.urlopen('http://example.com/somefile.zip')
除了解析原始 URL 之外,有没有一种简单的方法可以获取文件名?
编辑:将 openfile 更改为 urlopen...不知道这是怎么发生的。
编辑2:我最终使用了:
filename = url.split('/')[-1].split('#')[0].split('?')[0]
除非我弄错了,否则这也应该去除所有潜在的查询。
答:
你是说 ?模块中没有调用任何函数。urllib2.urlopen
openfile
urllib2
无论如何,请使用以下函数:urllib2.urlparse
>>> from urllib2 import urlparse
>>> print urlparse.urlsplit('http://example.com/somefile.zip')
('http', 'example.com', '/somefile.zip', '', '')
瞧。
我认为当涉及到 http 传输时,“文件名”并不是一个定义良好的概念。服务器可能(但不是必需的)提供一个作为“content-disposition”标头,您可以尝试使用 .如果此操作失败,则可能需要自行分析 URI。remotefile.headers['Content-Disposition']
你的意思是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'
评论
我想这取决于你所说的解析是什么意思。如果不解析 URL,就无法获取文件名,即远程服务器不会为您提供文件名。但是,您不必自己做太多事情,这里有一个模块:urlparse
In [9]: urlparse.urlparse('http://example.com/somefile.zip')
Out[9]: ('http', 'example.com', '/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,但也许仍然有助于:)
我不知道。
但是你可以像这样轻松地解析它:
url = 'http://example.com/somefile.zip'
print url.split('/')[-1]
如果你只想要文件名本身,假设末尾没有像 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 或文件路径的最后一部分。
评论
os.path
import posixpath; posixpath.basename
使用是最安全的选择:urlsplit
url = 'http://example.com/somefile.zip'
urlparse.urlsplit(url).path.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)
刚看到这个我通常做..
filename = url.split("?")[0].split("/")[-1]
该函数不仅适用于文件路径,也适用于网址,因此您不必自己手动解析网址。此外,请务必注意,您应该使用原始 url 代替原始 url 来跟踪重定向响应:os.path.basename
result.url
import os
import urllib2
result = urllib2.urlopen(url)
real_url = urllib2.urlparse.urlparse(result.url)
filename = os.path.basename(real_url.path)
您可以在此处使用简单的正则表达式。像这样:
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,它不是依赖于操作系统并优雅地处理 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 不会去任何地方)——只是使用标准解析规则。
您也可以将两个评分最高的答案结合起来: 使用 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)
评论
http://example.com/somefile/
http://example.com