如何在Python中find一个文件的MIMEtypes?
假设你想在一些地方保存一堆文件,例如在BLOB中。 假设您想通过网页浏览这些文件,并让客户端自动打开正确的应用程序/查看器。
假设:浏览器根据HTTP响应中的MIMEtypes(内容types?)标题确定使用哪个应用程序/查看器。
基于这个假设,除了文件的字节之外,还需要保存MIMEtypes。
你将如何find一个文件的MIMEtypes? 我目前在Mac上,但这也应该在Windows上。
浏览器在将文件发布到网页时是否添加此信息?
有没有一个整洁的Python库来find这些信息? 一个WebService或(甚至更好)一个可下载的数据库?
toivotuobuild议的python-magic方法已经过时了。 Python-magic的当前主干位于Github,并且基于那里的readme,findMIMEtypes就是这样完成的。
# For MIME types >>> import magic >>> mime = magic.Magic(mime=True) >>> mime.from_file("testdata/test.pdf") 'application/pdf' >>>
标准库中的mimetypes模块将从文件扩展名中确定/猜测MIMEtypes。
如果用户正在上传文件,则HTTPpost将包含文件的MIMEtypes以及数据。 例如,Django将这些数据作为UploadedFile对象的一个属性提供。
比使用mimetypes库更可靠的方法是使用python-magic包。
import magic m = magic.open(magic.MAGIC_MIME) m.load() m.file("/tmp/document.pdf")
这将等同于使用文件(1)。
在Django上,还可以确保MIMEtypes与UploadedFile.content_type相匹配。
这似乎很容易
>>> from mimetypes import MimeTypes >>> import urllib >>> mime = MimeTypes() >>> url = urllib.pathname2url('Upload.xml') >>> mime_type = mime.guess_type(url) >>> print mime_type ('application/xml', None)
请参阅旧post
有3个不同的库包装libmagic。
其中2个是可用的pypi(所以点安装将工作):
- filemagic
- python魔法
而另一个类似于python-magic的软件可以直接在最新的libmagic源代码中find,这是你的linux发行版中可能有的。
在Debian中,python-magic包就是关于这个的,它被用来作为toivotuo的说法,而不是像Simon Zimmermann所说的那样(恕我直言)。
在我看来,另一个(由libmagic的原作者)。
太糟糕了不能直接在pypi上使用。
在python 2.6中:
mime = subprocess.Popen("/usr/bin/file --mime PATH", shell=True, \ stdout=subprocess.PIPE).communicate()[0]
你没有说明你正在使用什么Web服务器,但是Apache有一个很好的叫做Mime Magic的小模块,当被告知时,它用它来确定文件的types。 它读取文件的一些内容,并尝试根据find的字符找出它的types。 正如Dave Webb提到的python下的MimeTypes模块可以工作,只要提供扩展名就方便了。
或者,如果您坐在UNIX机器上,则可以使用sys.popen('file -i ' + fileName, mode='r')
来获取MIMEtypes。 Windows应该有一个等效的命令,但我不确定它是什么。
在python3下,@toivotuo的方法对我来说工作得最好也最可靠。 我的目标是确定没有可靠的.gz扩展名的gzip文件。 我安装了python3-magic。
import magic filename = "./datasets/test" def file_mime_type(filename): m = magic.open(magic.MAGIC_MIME) m.load() return(m.file(filename)) print(file_mime_type(filename))
对于gzip文件,它返回:application / gzip; 字符集=二进制
对于一个解压缩的txt文件(iostat数据):text / plain; 字符集= US-ASCII
对于一个tar文件:application / x-tar; 字符集=二进制
对于一个bz2文件:application / x-bzip2; 字符集=二进制
最后但并非最不重要的一个.zip文件:application / zip; 字符集=二进制
mimetypes模块只是基于文件扩展名识别文件types。 如果您尝试恢复文件的文件types而不扩展名,则mimetypes将不起作用。
在Python 3.x和带有url的webapp中,不能有扩展名或假扩展名的文件。 你应该使用安装python-magic
pip3 install python-magic
对于Mac OS X,您还应该安装libmagic
brew install libmagic
代码片段
import urllib import magic from urllib.request import urlopen url = "http://...url to the file ..." request = urllib.request.Request(url) response = urlopen(request) mime_type = magic.from_buffer(response.readline()) print(mime_type)
或者你可以把一个大小的阅读
import urllib import magic from urllib.request import urlopen url = "http://...url to the file ..." request = urllib.request.Request(url) response = urlopen(request) mime_type = magic.from_buffer(response.read(128)) print(mime_type)
我已经尝试了很多的例子,但Django 诱变剂很好地玩。
示例检查文件是否是mp3
from mutagen.mp3 import MP3, HeaderNotFoundError try: audio = MP3(file) except HeaderNotFoundError: raise ValidationError('This file should be mp3')
缺点是你检查文件types的能力是有限的,但如果你不仅要检查文件types,而且要访问附加信息,这是一个很好的方法。
2017更新
不需要去github,它是在PyPi下以不同的名字:
pip install --user python-magic # or: sudo apt install python3-magic # Ubuntu distro package
代码也可以简化:
>>> import magic >>> magic.from_file('/tmp/img_3304.jpg', mime=True) 'image/jpeg'
这可能已经老了,但为什么不直接从Django使用UploadedFile.content_type? 是不是一样?( https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type )
你可以使用imghdr Python模块。