如何在python中找到文件的mime类型?

Dar*_*mas 177 python mime

假设您想在某处保存一堆文件,例如在BLOB中.假设你想通过网页将这些文件输出,并让客户端自动打开正确的应用程序/查看器.

假设:浏览器通过HTTP响应中的mime-type(content-type?)标头确定要使用的应用程序/查看器.

基于该假设,除了文件的字节外,您还希望保存MIME类型.

您如何找到文件的MIME类型?我目前在Mac上,但这也适用于Windows.

将文件发布到网页时,浏览器是否会添加此信息?

是否有一个整洁的python库来查找这些信息?WebService或(甚至更好)可下载的数据库?

Sim*_*ann 199

toivotuo建议的python-magic方法已经过时了.Python-magic的当前主干位于Github,基于自述文件,找到MIME类型,就像这样.

# For MIME types
>>> import magic
>>> mime = magic.Magic(mime=True)
>>> mime.from_file("testdata/test.pdf")
'application/pdf'
>>>
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的评论!请注意,"above"在stackoverflow中是一个困难的概念,因为排序按投票分组并在组内随机排序.我猜你是指@toivotuo的回答. (16认同)
  • 请注意,名为python-magic的debian/ubuntu包与同名的pip包不同.两者都是`import magic`但内容不兼容.有关更多信息,请参见http://stackoverflow.com/a/16203777/3189. (7认同)

Dav*_*ebb 81

标准库中的mimetypes模块将从文件扩展名中确定/猜测MIME类型.

如果用户正在上传文件,则HTTP帖子将包含文件的MIME类型以及数据.例如,Django使这些数据可用作UploadedFile对象的属性.

  • 文件扩展名不是确定mime类型的可靠方法. (55认同)
  • 如果文件存储在BLOB中,如问题中所指定,则您可能不知道文件扩展名. (12认同)
  • `import mimetypes``mimetypes.MimeTypes().guess_type(filename)[0]` (10认同)
  • 如果有一个例子,这个答案会更好. (6认同)
  • 在python 3.6中,这有效:`mimetypes.guess_type(path_file_to_upload)[1]` (3认同)
  • @cerin表示文件扩展名不可靠是正确的,但我刚刚发现,如https://github.com/所确认的,python-magic`的准确性(如顶部答案中所建议的)甚至更低。 s3tools / s3cmd / issues / 198。因此,“ mimetypes”对我来说似乎是一个更好的选择。 (2认同)
  • 虽然 @Cerin 基本上是正确的,但为 CSS、JavaScript 等获取“text/plain”,为包含大量非 ASCII 字符的 XML 获取“text/xml”(as ASCII)是完全无用的,甚至可能有害。因此,目前看来,mimetypes 是最佳选择。 (2认同)

小智 44

比使用mimetypes库更可靠的方法是使用python-magic包.

import magic
m = magic.open(magic.MAGIC_MIME)
m.load()
m.file("/tmp/document.pdf")
Run Code Online (Sandbox Code Playgroud)

这相当于使用file(1).

在Django上,还可以确保MIME类型与UploadedFile.content_type的MIME类型匹配.

  • 请参阅Simon Zimmermann的帖子,了解python-magic的更新用法 (2认同)

Lax*_*khi 28

这似乎很容易

>>> 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)
Run Code Online (Sandbox Code Playgroud)

请参考Old Post

  • for Python 3.X用urllib import request替换import urllib.然后使用"request"而不是urllib (5认同)
  • 我不认为你的例子中需要urllib. (4认同)

小智 10

有3个不同的库包含libmagic.

其中2个在pypi上可用(因此pip安装将起作用):

  • filemagic
  • 蟒蛇魔法

另外,类似于python-magic可以在最新的libmagic源代码中直接获得,它是你在linux发行版中可能拥有的那个.

在Debian中,包python-magic就是关于这一个,它被用作toivotuo所说的并且它没有像Simon Zimmermann所说的那样(恕我直言).

在我看来是另一种看法(由libmagic的原作者).

太糟糕了,不能直接在pypi上获得.


api*_*ito 9

在python 2.6中:

mime = subprocess.Popen("/usr/bin/file --mime PATH", shell=True, \
    stdout=subprocess.PIPE).communicate()[0]
Run Code Online (Sandbox Code Playgroud)

  • 这是不必要的,因为`file`命令基本上只是libmagic的包装器.您也可以使用python绑定(python-magic),就像Simon的回答一样. (6认同)
  • 这取决于操作系统.例如,在Mac OS X上,您在正常环境中拥有"文件"但不具有libmagic. (6认同)

bod*_*odo 7

Python绑定到libmagic

关于该主题的所有不同答案都非常令人困惑,因此我希望通过对libmagic的不同绑定的概述来更加清楚。以前,mammadori给出了一个简短的答案,列出了可用的选项。

魔力

确定文件mime-type时,简称为选择的工具,file其后端称为libmagic。(请参阅Project主页。)该项目是在私有cvs存储库中开发的,但是github上有一个只读的git mirror

现在,如果您想将任何libmagic绑定与python一起使用,则需要使用此工具,该工具已经附带了自己的python绑定,称为file-magic。它们没有太多专用的文档,但是您可以随时查看c-library的手册页:man libmagic自述文件中描述了基本用法:

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)
Run Code Online (Sandbox Code Playgroud)

除此之外,还可以通过Magic使用示例文件中magic.open(flags)所示的创建对象来使用库。

无论toivotuo和ewr2san使用这些file-magic绑定包含在file工具。他们错误地假设,他们正在使用该python-magic程序包。这似乎表明,如果同时安装filepython-magic,则python模块将magic引用前者。

蟒蛇魔术

这是西蒙·齐默尔曼(Simon Zimmermann)在回答中谈到的图书馆,该图书馆也被克劳德·库洛姆Claude COULOMBE)和格林哥·苏阿韦Gringo Suave)所采用

魔术师

注意:该项目的最新更新时间为2013年!

由于基于相同的c-api,因此该库与中file-magic包含的库有些相似libmagic。它仅由mammadori提及,没有其他答案使用它。


oet*_*tzi 7

python 3 参考:https : //docs.python.org/3.2/library/mimetypes.html

mimetypes.guess_type(url,strict=True) 根据 url 给出的文件名或 URL 猜测文件的类型。返回值是一个元组(类型、编码),如果类型无法猜测(缺少或未知后缀),则类型为 None 或“类型/子类型”形式的字符串,可用于 MIME 内容类型标头。

encoding 是 None 表示没有编码或用于编码的程序的名称(例如 compress 或 gzip)。该编码适合用作 Content-Encoding 标头,而不是用作 Content-Transfer-Encoding 标头。映射是表驱动的。编码后缀区分大小写;类型后缀首先区分大小写,然后不区分大小写。

可选的严格参数是一个标志,指定已知 MIME 类型列表是否仅限于在 IANA 注册的官方类型。当 strict 为 True(默认)时,仅支持 IANA 类型;当 strict 为 False 时,还会识别一些额外的非标准但常用的 MIME 类型。

import mimetypes
print(mimetypes.guess_type("sample.html"))
Run Code Online (Sandbox Code Playgroud)


Ped*_*ito 7

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
Run Code Online (Sandbox Code Playgroud)

现场演示


来自Python 文档

mimetypes.guess_type网址严格=真

根据url给出的文件名、路径或 URL 猜测文件的类型。URL 可以是字符串或类似路径的对象

返回值是一个元组(type, encoding),其中typeNone无法猜测类型(缺少或未知后缀)或 form 的字符串'type/subtype',可用于 MIME内容类型标头。

编码None对于没有编码或用于编码的程序的名称(例如压缩gzip的)。该编码适合用作Content-Encoding标头,而不是用作Content-Transfer-Encoding标头。映射是表驱动的。编码后缀区分大小写;类型后缀首先区分大小写,然后不区分大小写。

可选的严格参数是一个标志,指定已知 MIME 类型列表是否仅限于IANA 注册的官方类型。当严格True(默认)时,仅支持 IANA 类型;当strict is 时False,一些额外的非标准但常用的 MIME 类型也被识别。

在 3.8 版更改: 添加了对 url 作为path-like object 的支持


akd*_*dom 6

你没有说明你正在使用什么样的Web服务器,但Apache有一个很好的小模块叫做Mime Magic,它用来确定文件的类型.它会读取文件的一些内容,并根据找到的字符尝试找出它的类型.而正如Dave Webb提到的python下的MimeTypes模块将起作用,只要扩展是很方便的.

或者,如果您坐在UNIX机器上,则可以使用它sys.popen('file -i ' + fileName, mode='r')来获取MIME类型.Windows应该有一个等效的命令,但我不确定它是什么.

  • 现在你可以做subprocess.check_output(['file',' - b',' - mime',filename]) (7认同)

小智 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))
Run Code Online (Sandbox Code Playgroud)

对于gzip压缩文件,它返回:application/gzip; 字符集=二进制

对于解压缩的txt文件(iostat数据):text/plain; 字符集= US-ASCII

对于tar文件:application/x-tar; 字符集=二进制

对于bz2文件:application/x-bzip2; 字符集=二进制

最后但并非最不重要的一个.zip文件:application/zip; 字符集=二进制


Gri*_*ave 6

2017更新

无需转到github,它以其他名称位于PyPi上:

pip3 install --user python-magic
# or:
sudo apt install python3-magic  # Ubuntu distro package
Run Code Online (Sandbox Code Playgroud)

代码也可以简化:

>>> import magic

>>> magic.from_file('/tmp/img_3304.jpg', mime=True)
'image/jpeg'
Run Code Online (Sandbox Code Playgroud)


Cla*_*MBE 5

在Python 3.x和webapp中,文件的url没有扩展名或伪扩展名.你应该使用安装python-magic

pip3 install python-magic
Run Code Online (Sandbox Code Playgroud)

对于Mac OS X,您还应该安装libmagic

brew install libmagic
Run Code Online (Sandbox Code Playgroud)

代码段

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)
Run Code Online (Sandbox Code Playgroud)

或者你可以在阅读中加入一个大小

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)
Run Code Online (Sandbox Code Playgroud)


小智 5

我首先尝试 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
Run Code Online (Sandbox Code Playgroud)