PythonでファイルのMIMEタイプを見つける方法は?


193

たとえば、BLOBなど、どこかに大量のファイルを保存したいとします。これらのファイルをWebページ経由で表示し、クライアントに適切なアプリケーション/ビューアを自動的に開かせたいとします。

前提:ブラウザは、HTTP応答のmime-type(content-type?)ヘッダーで使用するアプリケーション/ビューアを特定します。

その仮定に基づいて、ファイルのバイトに加えて、MIMEタイプも保存する必要があります。

ファイルのMIMEタイプをどのように見つけますか?私は現在Macを使っていますが、これはWindowsでも動作するはずです。

ブラウザは、ファイルをWebページに投稿するときにこの情報を追加しますか?

この情報を見つけるためのきちんとしたPythonライブラリはありますか?WebServiceまたは(さらに良い)ダウンロード可能なデータベース?

回答:


217

toivotuoによって提案されたpython-magicメソッドは古くなっています。Python-magicの現在のトランクはGithubにあり、そこのreadmeに基づいて、MIMEタイプを見つけることは次のように行われます。

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

17
コメントありがとうございます!順序は投票によってグループ化され、グループ内でランダムに順序付けられるため、「上」はスタックオーバーフローでは難しい概念であることに注意してください。@toivotuoの答えを参照していると思います。
Daren Thomas

1
ええ、私はこの返信を書いている時点でコメントを作成するのに十分な「ポイント」がありませんでした。しかし、おそらく@toivotuoが彼の質問を編集できるように、コメントとしてそれを書くべきでした。
Simon Zimmermann

1
rpm -qf /usr/lib/python2.7/site-packages/magic.py -i URL:darwinsys.com/file 概要:libmagic APIのPythonバインディングrpm -qf / usr / bin / file -i名前:ファイルURL:darwinsys.com/file からのpython-魔法darwinsys.com/fileさんが言っtoivotuoとLinuxのFedoraが付属しています@のように動作します。そして、よりメインストリームのようです。
セルジオ2011年

7
python-magicという名前のdebian / ubuntuパッケージは、同じ名前のpipパッケージとは異なることに注意してください。どちらもimport magic互換性のない内容です。詳細については、stackoverflow.com / a / 16203777/3189を参照してください。
Hamish Downer

1
toivotuoの回答についてコメントしたところ、古くはありません。別のライブラリについて話している。回答のそのステートメントを削除または置き換えてください。現在、最適なソリューションを見つけることは非常に困難です。
bodo

86

標準ライブラリのmimetypesモジュールは、ファイル拡張子からMIMEタイプを決定/推測します。

ユーザーがファイルをアップロードしている場合、HTTPポストには、データと共にファイルのMIMEタイプが含まれます。たとえば、DjangoはこのデータをUploadedFileオブジェクトの属性として利用できるようにします。


12
質問で指定されているように、ファイルがBLOBに格納されている場合、ファイル拡張子がわからない可能性があります。
メカニカルカタツムリ2011

55
ファイル拡張子は、mimeタイプを判別する信頼できる方法ではありません。
セリン

12
import mimetypes mimetypes.MimeTypes().guess_type(filename)[0]
ジョナサン

4
Python 3.6ではこれは機能します:mimetypes.guess_type(path_file_to_upload)[1]
JinSnow

3
@cerinはファイル拡張子が信頼できないことは正しいですが、私はちょうどの正確さを発見しました python-magicgithub.com / s3tools / s3cmd / issues / 198で確認されているように、(上位の回答で提案されているように)がさらに低いことを発見しました。だから、mimetypes私にとってはより良い候補のようです。
ダンキン

46

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のタイプと一致することを確認することもできます。


2
python-magicの更新された使用法についてはSimon Zimmermannの投稿を参照してください
Daren Thomas

@DarenThomas:マンマドリの回答で述べたように、この回答は古くなく、Simon Zimmermannのソリューションとは異なります。ファイルユーティリティがインストールされている場合は、おそらくこのソリューションを使用できます。ファイル5.32.32で動作します。gentooでは、ファイルパッケージに対してPython USE-flagを有効にする必要もあります。
bodo

35

これはとても簡単なようです

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

ご参照ください 古いポストを

更新 -@Garretsコメントによると、Python 3ではよりシンプルです。

import mimetypes
print(mimetypes.guess_type("sample.html"))

4
あなたの例ではurllibは必要ないと思います。
BrotherJack 2014

5
Python 3.Xの場合、インポートurllibをfrom urllibインポートリクエストに置き換えます。そして、urllibの代わりに "request"を使用します
Arjun Thakur

1
Python 2.7でも動作します
Jay Modi

@oetziのソリューションはこのモジュールを使用しますが、より簡単です。
Garrett

11

libmagicをラップする3つの異なるライブラリがあります。

それらの2つはpypiで利用可能です(したがって、pipのインストールは機能します)。

  • filemagic
  • python-magic

また、python-magicと同様に、最新のlibmagicソースで直接入手でき、おそらくLinuxディストリビューションに含まれています。

Debianのパッケージpython-magicはこれに関するもので、toivotuoが言うように使用されており、Simon Zimmermannが言ったように廃止されていません(IMHO)。

それは私には別の見方です(libmagicの元の作者による)。

残念ながら、pypiでは直接利用できません。


便宜上、リポジトリを追加しました。github.com / mammadori / magicpip install -e git://github.com/mammadori/magic-python.git#egg=Magic_file_extensions
python

10

Python 2.6:

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

6
fileコマンドは基本的にlibmagicのラッパーなので、これは不要です。Simonの回答のように、Pythonバインディング(python-magic)を使用することもできます。
メカニカルカタツムリ2011

6
これはオペレーティングシステムによって異なります。たとえばMac OS Xでは、通常の環境では「ファイル」はありますが、libmagicはありません。
rptb1 2013年

9

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'

あなたはjsまたはcssファイルに対して同じことをできますか?
kumbhanibhavesh

もちろん??
Gringo Suave 2018

9

libmagicへのPythonバインディング

このトピックに関するさまざまな答えはすべて非常に混乱するので、libmagicのさまざまなバインディングのこの概要をもう少し明確にしたいと思っています。以前はマンマドリが短い答えを出しました利用可能なオプションをリストし提供しました。

libmagic

ファイルのMIMEタイプを判別する場合、選択したツールが呼び出されfile、そのバックエンドが呼び出されlibmagicます。(プロジェクトのホームページを参照してください。)プロジェクトはプライベートcvs-repositoryで開発されていますが、githubに読み取り専用のgitミラーがあります。

pythonでlibmagicバインディングのいずれかを使用する場合に必要になるこのツールには、という独自のpythonバインディングがすでに付属していますfile-magic。専用のドキュメントはあまりありませんが、c-libraryのmanページをいつでも確認できますman libmagic。基本的な使用法は、readmeファイルで説明されています

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)してオブジェクトを作成することにより、ライブラリを使用することもできます

toivotuoとewr2sanはどちらもfile-magicfileツールに含まれているこれらのバインディングを使用します。彼らは誤ってpython-magicパッケージを使用していると思い込んでいます。これは、両方の場合ことを、示しているようだfilepython-magicインストールされている、Pythonのモジュールはmagic前者を指します。

python-magic

これは、Simon Zimmermannが彼の回答で話しているライブラリで、Claude COULOMBEGringo Suaveでも使用されています。

filemagic

:このプロジェクトは2013年に最後に更新されました!

同じc-apiに基づいているため、このライブラリにはにfile-magic含まれるものといくつかの類似点がありlibmagicます。それはマンマドリによってのみ言及され、他の答えはそれを採用していません。


7

@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圧縮されたファイルの場合、次を返します:application / gzip; charset = binary

解凍されたtxtファイル(iostatデータ)の場合:text / plain; charset = us-ascii

tarファイルの場合:application / x-tar; charset = binary

bz2ファイルの場合:application / x-bzip2; charset = binary

そして最後に、私にとっては.zipファイル:application / zip; charset = binary


7

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

mimetypes.guess_type(url、strict = True)urlで指定されたファイル名またはURLに基​​づいてファイルのタイプを推測します。戻り値はタプル(タイプ、エンコーディング)であり、タイプを推測できない場合(タイプが不明またはサフィックスが不明)、タイプが「タイプ/サブタイプ」の文字列で、MIMEコンテンツタイプヘッダーに使用できます。

エンコーディングがない場合、またはエンコーディングに使用するプログラムの名前(compressやgzipなど)の場合、encodingはNoneです。エンコーディングは、Content-Transfer-Encodingヘッダーとしてではなく、Content-Encodingヘッダーとしての使用に適しています。マッピングはテーブル駆動です。エンコーディングサフィックスでは大文字と小文字が区別されます。タイプサフィックスは、最初に大文字と小文字を区別して試行され、次に大文字と小文字を区別せずに試行されます。

オプションのstrict引数は、既知のMIMEタイプのリストをIANAに登録されている公式のタイプのみに制限するかどうかを指定するフラグです。strictがTrue(デフォルト)の場合、IANAタイプのみがサポートされます。strictがFalseの場合、標準ではないが一般的に使用されるいくつかの追加のMIMEタイプも認識されます。

import mimetypes
print(mimetypes.guess_type("sample.html"))

6

どのWebサーバーを使用しているかは明記していませんが、ApacheにはMime Magicと呼ばれる素敵な小さなモジュールがあり、指示されたときにファイルのタイプを判別するために使用します。ファイルのコンテンツの一部を読み取り、見つかった文字に基づいて、ファイルのタイプを特定しようとします。また、Dave Webbが言及したように、拡張機能が便利であれば、PythonでMimeTypesモジュールが機能します。

または、UNIXボックスを使用sys.popen('file -i ' + fileName, mode='r')している場合は、MIMEタイプを取得するために使用できます。Windowsには同等のコマンドが必要ですが、それが何であるかはわかりません。


7
今日では、単にsubprocess.check_output(['file'、 '-b'、 '--mime'、filename])を実行できます
Nathan Villaescusa

python-magicが同等のことをすべてラップされて居心地よく行う場合、外部ツールを使用する理由は本当にありません。
2013年

4

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)

ファイル全体をロードしますか?
吴毅凡

いいえ、それはストリームなので、通常は数バイトです。
Claude COULOMBE 2017年

response.readline()またはresponse.read(128)で編集しましたありがとうございます。
Claude COULOMBE 2017年

3

最初にmimetypesライブラリを試します。動作しない場合は、代わりにpython-magicライブラリを使用します。

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

1

mimetypesモジュールは、ファイル拡張子に基づいてファイルタイプを認識するだけです。拡張子のないファイルのファイルタイプを復元しようとすると、mimetypesは機能しません。


3
それは本当ではないと思います。MIMEタイプは、データ形式を他の人にどのように伝えるかに関するものであり、自分でデータ形式を見つける方法に関するものではありません。拡張子のみに基づいて形式を推測し、MIMEタイプを出力するツールを使用する場合、ファイル拡張子がない場合はそのツールを使用できません。ただし、パーサーで確認するなど、他の方法で形式を推測することもできます。
erikbwork 2013

1

誰もそれについて言及しなかったことに私は驚いていますが、Pygmentsは特にテキスト文書のMIMEタイプについて教育を受けた推測を行うことができます。

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のドキュメント形式のうちどれが使用されているかを知る必要がある場合、これはかなり便利です。


0

私はたくさんの例を試しましたが、Djangoを使うと変異原性がうまくいきます。

ファイルがあるかどうかを確認する例 mp3

from mutagen.mp3 import MP3, HeaderNotFoundError  

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

欠点は、ファイルの種類をチェックする機能が制限されていることですが、ファイルの種類をチェックするだけでなく、追加情報にアクセスする場合にも優れた方法です。


セキュリティもチェックする必要があります
Artem Bernatskyi 2017



-1

imghdr Pythonモジュールを使用できます。


1
これは例を挙げておらず、実際にimghdrがどのようにまたはなぜここで役立つのかを実際に述べていないため、これは有用なコメントではありません。
erikbwork 2013

2
はい、わかりました。1年以上前ですが、私のようにこの質問を検索している人がまだいるので、更新できるかもしれません。助けが必要な場合は教えてください。
erikbwork 2013

1
画像タイプの非常に限られたリストでのみ機能します。これは、テキストファイル等、圧縮されたアーカイブ、文書フォーマット、程度は考えていません
tripleee
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.