假设您要在某处保存一堆文件,例如在BLOB中。假设你想通过网页发送这些文件,并让客户端自动打开正确的应用程序/查看器。
假设:浏览器通过HTTP响应中的mime-type(content-type?)标头确定要使用的应用程序/查看器。
基于该假设,除了文件的字节外,您还希望保存MIME类型。
您如何找到文件的MIME类型?我目前在Mac上,但这也适用于Windows。
浏览器在将文件发布到网页时是否会添加此信息?
是否有一个整洁的python库来查找这些信息? WebService或(甚至更好)可下载的数据库?
答案 0 :(得分:185)
toivotuo建议的python-magic方法已经过时了。 Python-magic's当前主干在Github,根据自述文件,找到MIME类型,就像这样。
# For MIME types
>>> import magic
>>> mime = magic.Magic(mime=True)
>>> mime.from_file("testdata/test.pdf")
'application/pdf'
>>>
答案 1 :(得分:80)
标准库中的mimetypes module将从文件扩展名中确定/猜测MIME类型。
如果用户正在上传文件,HTTP帖子将包含文件的MIME类型以及数据。例如,Django将此数据作为UploadedFile对象的属性提供。
答案 2 :(得分:43)
比使用mimetypes库更可靠的方法是使用python-magic包。
import magic
m = magic.open(magic.MAGIC_MIME)
m.load()
m.file("/tmp/document.pdf")
这相当于使用file(1)。
在Django上,还可以确保MIME类型与UploadedFile.content_type匹配。
答案 3 :(得分:25)
这似乎很容易
>>> 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)
请参阅Old Post
答案 4 :(得分:10)
有3个不同的图书馆包含了libmagic。
其中2个在pypi上可用(因此pip install将起作用):
另外,类似于python-magic可以在最新的libmagic源代码中直接使用,它就是你在Linux发行版中可能拥有的那个。
在Debian中,python-magic包是关于这个的,它被用作toivotuo说,并没有像Simon Zimmermann所说的那样(IMHO)。
在我看来,另一种看法(由libmagic的原作者)。
太糟糕了,不能直接在pypi上使用。
答案 5 :(得分:9)
在python 2.6中:
mime = subprocess.Popen("/usr/bin/file --mime PATH", shell=True, \
stdout=subprocess.PIPE).communicate()[0]
答案 6 :(得分:6)
你没有说明你使用的是什么Web服务器,但是Apache有一个很好的小模块叫Mime Magic,它用来确定文件的类型。它会读取文件的一些内容,并根据找到的字符尝试找出它的类型。并且Dave Webb Mentioned python下的MimeTypes Module将起作用,只要扩展名很方便。
或者,如果您坐在UNIX框中,则可以使用sys.popen('file -i ' + fileName, mode='r')
来获取MIME类型。 Windows应该有一个等效的命令,但我不确定它是什么。
答案 7 :(得分:6)
13 年后...
此页面上有关 python 3 的大多数答案已过时或不完整。
获取我使用的 mime 类型:
import mimetypes
mt = mimetypes.guess_type("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
if mt:
print("Mime Type:", mt[0])
else:
print("Cannot determine Mime Type")
# Mime Type: application/pdf
来自Python docs:
mimetypes.guess_type
(url, strict=True)
根据 url 给出的文件名、路径或 URL 猜测文件的类型。 URL 可以是字符串或 path-like object。
返回值是一个元组 (type, encoding)
,其中 type 是 None
,如果类型不能被猜测(缺少或未知后缀)或形式为 { {1}},可用于 MIME content-type 标头。
encoding 是 'type/subtype'
表示无编码或用于编码的程序名称(例如 compress 或 gzip)。该编码适合用作 Content-Encoding 标头,不 用作 Content-Transfer-Encoding 标头。映射是表驱动的。编码后缀区分大小写;类型后缀首先尝试区分大小写,然后不区分大小写。
可选的 strict 参数是一个标志,用于指定已知 MIME 类型列表是否仅限于官方类型 registered with IANA。当 strict 为 None
(默认)时,仅支持 IANA 类型;当 strict 为 True
时,还可以识别一些额外的非标准但常用的 MIME 类型。
在 3.8 版更改:添加了对 url 为 path-like object 的支持。
答案 8 :(得分:6)
@toivotuo的方法在python3下对我来说效果最好,最可靠。我的目标是识别没有可靠的.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压缩文件: 应用/ gzip的;字符集=二进制
用于解压缩的txt文件(iostat数据): 文本/无格式;字符集= US-ASCII
表示tar文件: 应用程序/ x-焦油;字符集=二进制
对于bz2文件: 应用程序/ x-的bzip2;字符集=二进制
最后但并非最不重要的是.zip文件: 应用程序/压缩;字符集=二进制
答案 9 :(得分:5)
在Python 3.x和webapp中,文件的url没有扩展名或虚假扩展名。你应该使用
安装python-magicpackage com.wavedevelopers.databaseasynctaskdemo;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.widget.ListView;
import android.widget.Toast;
/**
* Created by Haider885 on 25/08/2016.
*/
public class BackgrounTask extends AsyncTask<String,Product,String> {
Context ctx;
ProductAdapter productAdapter;
Activity activity;
ListView listView;
BackgrounTask(Context ctx)
{
this.ctx = ctx;
activity = (Activity) ctx;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
String method = params[0];
DbOperation dbOperation = new DbOperation(ctx);
if (method.equals("add_info"))
{
String id = params[1];
String name = params[2];
float price = Float.parseFloat(params[3]);
float qty = Float.parseFloat(params[4]);
float total = Float.parseFloat(params[5]);
SQLiteDatabase db = dbOperation.getWritableDatabase();
dbOperation.addProduct(db,id,name,price,qty,total);
return "Saved...";
}
else if (method.equals("get_info"))
{
SQLiteDatabase db = dbOperation.getReadableDatabase();
Cursor cursor = dbOperation.getInformation(db);
productAdapter = new ProductAdapter(ctx,R.layout.display_product_row);
listView = (ListView) activity.findViewById(R.id.display_listview);
String id,name;
float price,qty,total;
while (cursor.moveToNext())
{
id = cursor.getString(cursor.getColumnIndex(ProductContract.ProductEntry.ID));
name = cursor.getString(cursor.getColumnIndex(ProductContract.ProductEntry.NAME));
price = cursor.getFloat(cursor.getColumnIndex(ProductContract.ProductEntry.PRICE));
qty = cursor.getFloat(cursor.getColumnIndex(ProductContract.ProductEntry.QTY));
total = cursor.getFloat(cursor.getColumnIndex(ProductContract.ProductEntry.TOTAL));
Product product = new Product(id,name,price,qty,total);
publishProgress(product);
}
return "get_info";
}
return null;
}
@Override
protected void onProgressUpdate(Product... values) {
productAdapter.add(values[0]);
}
@Override
protected void onPostExecute(String result) {
if (result.equals("get_info"))
{
listView.setAdapter(productAdapter);
}
else {
Toast.makeText(ctx, result, Toast.LENGTH_SHORT).show();
}
}
}
对于Mac OS X,您还应该使用
安装libmagicpip3 install python-magic
代码段
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)
答案 10 :(得分:5)
2017年更新
不需要去github,它是以不同的名字出现在PyPi上的:
pip3 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'
答案 11 :(得分:5)
关于该主题的所有不同答案都非常令人困惑,因此我希望通过对libmagic的不同绑定的概述来更加清楚。以前,mammadori给short answer列出了可用的选项。
magic
确定文件的mime类型时,选择的工具简称为file
,其后端称为libmagic
。 (请参见Project home page。)该项目是在私有cvs存储库中开发的,但是有一个read-only git mirror on github。
现在,如果您想将任何libmagic绑定与python一起使用,则需要使用此工具,该工具已经附带了自己的称为file-magic
的python绑定。它们没有太多专用的文档,但是您随时可以查看c库的手册页:man libmagic
。 readme file中描述了基本用法:
import magic
detected = magic.detect_from_filename('magic.py')
print 'Detected MIME type: {}'.format(detected.mime_type)
print 'Detected encoding: {}'.format(detected.encoding)
print 'Detected file type name: {}'.format(detected.name)
除此之外,您还可以通过使用Magic
创建magic.open(flags)
对象来使用该库,如example file所示。
toivotuo和ewr2san都使用file-magic
工具中包含的这些file
绑定。他们错误地假设,他们正在使用python-magic
包。 这似乎表明,如果同时安装了file
和python-magic
,则python模块magic
指的是前一个。
magic
这是Simon Zimmermann在his answer中谈论的库,Claude COULOMBE和Gringo Suave也使用了该库。
magic
注意:该项目的最新更新时间为2013年!
由于基于相同的c-api,所以该库与file-magic
中包含的libmagic
有一些相似之处。 mammadori仅提及了此内容,没有其他答案使用它。
答案 12 :(得分:4)
python 3参考:https://docs.python.org/3.2/library/mimetypes.html
mimetypes.guess_type(url,strict = True)猜测基于文件的类型 在其文件名或URL(由url给出)上。返回值是一个元组 (类型,编码),如果无法猜测类型,则类型为“无” (缺少或后缀未知)或“类型/子类型”形式的字符串, 可用于MIME内容类型标头。
encoding为None表示没有编码或用于 编码(例如compress或gzip)。该编码适合用作 Content-Encoding标头,而不是Content-Transfer-Encoding标头。 映射是表驱动的。编码后缀区分大小写; 类型后缀首先要区分大小写,然后再区分大小写 麻木不仁。
可选的strict参数是一个标志,用于指定是否列出 已知的MIME类型仅限于向MIME注册的正式类型 IANA。如果strict为True(默认值),则仅IANA类型为 支持的;当strict为False时,一些其他非标准但 也可以识别常用的MIME类型。
import mimetypes
print(mimetypes.guess_type("sample.html"))
答案 13 :(得分:3)
mimetypes模块只根据文件扩展名识别文件类型。如果您尝试恢复没有扩展名的文件的文件类型,则mimetypes将无效。
答案 14 :(得分:1)
令我惊讶的是,没有人提到它,但是Pygments能够对特定的哑剧类型(尤其是文本文档)做出有根据的猜测。
Pygments实际上是一个Python语法突出显示库,但是它具有一种方法,可以根据您的猜测来判断您的文档是500种受支持的文档类型中的哪一种。 即c ++ vs C#vs Python vs等
import inspect
def _test(text: str):
from pygments.lexers import guess_lexer
lexer = guess_lexer(text)
mimetype = lexer.mimetypes[0] if lexer.mimetypes else None
print(mimetype)
if __name__ == "__main__":
# Set the text to the actual defintion of _test(...) above
text = inspect.getsource(_test)
print('Text:')
print(text)
print()
print('Result:')
_test(text)
输出:
Text:
def _test(text: str):
from pygments.lexers import guess_lexer
lexer = guess_lexer(text)
mimetype = lexer.mimetypes[0] if lexer.mimetypes else None
print(mimetype)
Result:
text/x-python
现在,这还不是很完美,但是如果您需要知道使用的是500种文档格式中的哪一种,那将非常有用。
答案 15 :(得分:0)
我尝试过很多例子,但Django mutagen很好玩。
检查文件是否为mp3
from mutagen.mp3 import MP3, HeaderNotFoundError
try:
audio = MP3(file)
except HeaderNotFoundError:
raise ValidationError('This file should be mp3')
缺点是您检查文件类型的能力有限,但如果您不仅要检查文件类型还要访问其他信息,这是一个很好的方法。
答案 16 :(得分:0)
这可能已经过时了,但为什么不直接从Django使用UploadedFile.content_type?不一样吗?(https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type)
答案 17 :(得分:0)
For byte Array type data you can use magic.from_buffer(_byte_array,mime=True)
答案 18 :(得分:0)
我首先尝试mimetypes库。如果不起作用,我改用python-magic libary。
import mimetypes
def guess_type(filename, buffer=None):
mimetype, encoding = mimetypes.guess_type(filename)
if mimetype is None:
try:
import magic
if buffer:
mimetype = magic.from_buffer(buffer, mime=True)
else:
mimetype = magic.from_file(filename, mime=True)
except ImportError:
pass
return mimetype
答案 19 :(得分:-1)
您可以使用 imghdr Python模块。