如何安全地从URL获取文件扩展名?
考虑以下这些网址:
http://m3u.com/tunein.m3u http://asxsomeurl.com/listen.asx:8024 http://www.plssomeotherurl.com/station.pls?id=111 http://22.198.133.16:8024
怎样才能正确判断文件的扩展名(.m3u/.asx/.pls)呢?很明显,最后一个没有扩展名。
补充说明:我忘了提到,m3u、asx 和 pls 是用于音频流的播放列表(文本文件),需要用不同的方式来解析。我们的目标是确定扩展名,然后把网址发送到合适的解析函数。例如,
url = argv[1]
ext = GetExtension(url)
if ext == "pls":
realurl = ParsePLS(url)
elif ext == "asx":
realurl = ParseASX(url)
(etc.)
else:
realurl = url
Play(realurl)
GetExtension() 应该返回文件的扩展名(如果有的话),最好是在不连接到网址的情况下完成。
10 个回答
48
使用 requests
和 mimetypes
这两个工具来处理这个问题是最简单的。
import requests
import mimetypes
response = requests.get(url)
content_type = response.headers['content-type']
extension = mimetypes.guess_extension(content_type)
文件的扩展名是以点开头的。例如,extension
对于内容类型 'image/png'
来说,就是 '.png'
。
58
使用 urlparse
来从网址中提取路径,然后用 os.path.splitext
来获取文件的扩展名。
import os
try:
import urlparse
except ImportError:
from urllib.parse import urlparse
url = 'http://www.plssomeotherurl.com/station.pls?id=111'
path = urlparse.urlparse(url).path
ext = os.path.splitext(path)[1]
需要注意的是,文件的扩展名可能并不能准确反映文件的类型。HTTP 的 Content-Type
头信息可能更可靠。
25
真正正确的方法是根本不使用文件扩展名。你可以对相关的URL发起一个GET(或者HEAD)请求,然后查看返回的“Content-type”这个HTTP头信息来获取内容类型。文件扩展名并不可靠。
想了解更多信息和一些有用的MIME类型,可以查看MIME类型(IANA媒体类型)。