假设您想要将一堆文件保存在某个地方,例如保存在 BLOB 中。假设您想通过网页分发这些文件,并让客户端自动打开正确的应用程序/查看器。

假设:浏览器通过 HTTP 响应中的 mime-type(内容类型?)标头确定要使用哪个应用程序/查看器。

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

如何找到文件的 MIME 类型?我目前使用的是 Mac,但这也应该适用于 Windows。

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

有没有一个简洁的 python 库来查找这些信息?Web 服务还是(更好)可下载的数据库?

有帮助吗?

解决方案

toivotuo 建议的 python-magic 方法已经过时了。 Python 魔法 当前主干位于 Github,根据那里的自述文件,找到 MIME 类型,就是这样完成的。

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

其他提示

模仿类型模块 标准库中的内容将根据文件扩展名确定/猜测 MIME 类型。

如果用户上传文件,HTTP post 将包含文件的 MIME 类型以及数据。例如,Django 将此数据作为 上传文件 目的。

比使用 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 匹配。

这似乎很容易

>>> 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)

请参考 旧帖子

有 3 个不同的库包装了 libmagic。

其中 2 个可在 pypi 上使用(因此 pip install 可以工作):

  • 文件魔法
  • python 魔法

另一种与 python-magic 类似的方法可以直接在最新的 libmagic 源代码中找到,并且您的 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 有一个很好的小模块,名为 哑剧魔术 当被告知这样做时,它用它来确定文件的类型。它读取文件的一些内容,并尝试根据找到的字符确定文件的类型。并作为 戴夫·韦伯提到MimeTypes 模块 在 python 下可以工作,只要有一个方便的扩展。

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

@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-tar;字符集=二进制

对于 bz2 文件:应用程序/x-bzip2;字符集=二进制

最后但并非最不重要的是我的 .zip 文件:应用程序/zip;字符集=二进制

在 Python 3.x 和 webapp 中,带有 url 的文件不能有扩展名或假扩展名。你应该安装 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)

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'

Python 与 libmagic 的绑定

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

libmagic

当确定文件 mime 类型时,只需调用所选择的工具 file 它的后端称为 libmagic. 。(参见 项目主页.)该项目是在私有cvs存储库中开发的,但是有一个 github上的只读git镜像.

现在,如果您想将任何 libmagic 绑定与 python 一起使用,您将需要这个工具,它已经附带了自己的 python 绑定,称为 file-magic. 。没有太多专门的文档,但您可以随时查看 c 库的手册页: 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)

除此之外,您还可以通过创建一个来使用该库 Magic 对象使用 magic.open(flags) 如图所示 示例文件.

两个都 托伊沃托 和 ewr2san 使用这些 file-magic 绑定包含在 file 工具。他们错误地认为,他们正在使用 python-magic 包裹。 这似乎表明,如果两者 filepython-magic 已安装,python 模块 magic 指的是前一种。

python 魔法

这就是西蒙·齐默尔曼 (Simon Zimmermann) 所说的图书馆 他的回答 并且也受雇于 克劳德·库隆贝温文尔雅的外国佬.

文件魔法

笔记: :该项目最后一次更新是在 2013 年!

由于基于相同的 c-api,该库与 file-magic 包括在 libmagic. 。它仅被提及 马马多里 并且没有其他答案使用它。

mimetypes 模块仅根据文件扩展名识别文件类型。如果您尝试恢复不带扩展名的文件的文件类型,则 mimetypes 将不起作用。

我已经尝试了很多例子,但是使用 Django 诱变剂 玩得很好。

检查文件是否存在的示例 mp3

from mutagen.mp3 import MP3, HeaderNotFoundError  

try:
    audio = MP3(file)
except HeaderNotFoundError:
    raise ValidationError('This file should be mp3')

缺点是您检查文件类型的能力有限,但如果您不仅想检查文件类型还想访问其他信息,那么这是一个很好的方法。

这可能已经很旧了,但为什么不直接从 Django 使用 UploadedFile.content_type 呢?不一样?(https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type)

对于字节数组类型数据,您可以使用魔法。from_buffer(_byte_array,mime = true)

我首先尝试 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

您可以使用 伊姆赫德 Python 模块。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top