LoginSignup
15
6

More than 3 years have passed since last update.

Python で MIME Type を取得する

Posted at

はじめに

Python の標準ライブラリの mimetypes モジュール を使って、
MIME Type を取得しようとしたら少しだけハマったのでメモを残す。

公式ドキュメント にもしっかり書いてあるが、
「ファイル名拡張子に関連付けられた MIME 型とを変換します」 となっている。
どうやらファイル名に含まれる拡張子しか見てくれていないっぽい。

今回は拡張子は無しの状態でファイルを判定したかったので、
mimetypes モジュールではダメだったというお話です。

mimetypes モジュール で試してみた

対象のファイルは png 画像

main.py
import mimetypes

IMAGE_FILE_PATH = './image.png'

print('===== .png =====')
print(f'-- mimetypes: {mimetypes.guess_type(IMAGE_FILE_PATH)[0]}')
実行結果
$ python main.py 
===== .png =====
-- mimetypes: image/png

ちゃんと取れてます。

拡張子無しで試す

main.py
import mimetypes
import shutil

IMAGE_FILE_PATH = './image.png'

print('===== 拡張子無し =====')
tmp = './dummy_image'
shutil.copy(IMAGE_FILE_PATH, tmp)
print(f'-- mimetypes: {mimetypes.guess_type(tmp)[0]}')
実行結果
$ python main.py 
===== 拡張子無し =====
-- mimetypes: None

None になってしまった。

.mp4 に偽装して試してみる

main.py
import mimetypes
import shutil

IMAGE_FILE_PATH = './image.png'

print('===== 拡張子を .mp4 の偽装 =====')
tmp = './dummy_image.mp4'
shutil.copy(IMAGE_FILE_PATH, tmp)
print(f'-- mimetypes: {mimetypes.guess_type(tmp)[0]}')
実行結果
$ python main.py 
===== 拡張子を .mp4 の偽装 =====
-- mimetypes: video/mp4

video/mp4 と判断されてしまった。

代わりに python-magic モジュールを使用

python-magiclibmagic を使ってファイル種別を判定してくれる。
また libmagic を使用するため、実行環境に libmagic がインストールされている必要がある

インストールされていない場合は以下のように実行時にエラーが出てしまいます。

libmagicがインストールされていない環境でpython-magicを使った時のエラー
ImportError: failed to find libmagic.  Check your installation

libmagic をインストール

自分は Mac を使用しているため、Homebrew でインストールしました。

libmagicをインストール
$ brew install libmagic

python-magic をインストール

まずは python-magic モジュールをインストール

$ pip install python-magic

python-magic モジュールで試してみた

試し方は前述の mimetypes モジュールと同じです。

  • png 画像
  • 上記をコピーした拡張子無しファイル
  • 同様に拡張子を .mp4 にしたファイル

png 画像

main.py
import magic

IMAGE_FILE_PATH = './image.png'

print('===== .png =====')
print(f'-- python-magic: {magic.from_file(IMAGE_FILE_PATH, mime=True)}')
実行結果
$ python main.py 
===== .png =====
-- python-magic: image/png

普通に取得できます。

拡張子無し

main.py
import shutil

import magic

IMAGE_FILE_PATH = './image.png'

print('===== 拡張子無し =====')
tmp = './dummy_image'
shutil.copy(IMAGE_FILE_PATH, tmp)
print(f'-- python-magic: {magic.from_file(tmp, mime=True)}')
実行結果
$ python main.py 
===== 拡張子無し =====
-- python-magic: image/png

mimetypes では None だったのに対し、ちゃんと取得できています。

.mp4 に偽装

main.py
import shutil

import magic

IMAGE_FILE_PATH = './image.png'

print('===== 拡張子を .mp4 の偽装 =====')
tmp = './dummy_image.mp4'
shutil.copy(IMAGE_FILE_PATH, tmp)
print(f'-- python-magic: {magic.from_file(tmp, mime=True)}')
実行結果
$ python main.py 
===== 拡張子を .mp4 の偽装 =====
-- python-magic: image/png

mimetypes では video/mp4 だったのに対し、ちゃんと取得できています。

まとめ

ファイル種別判定には mimetypes より python-magic を使ったほうが良い!

main.py
import mimetypes
import shutil

import magic

IMAGE_FILE_PATH = './image.png'

print('===== .png =====')
print(f'-- mimetypes: {mimetypes.guess_type(IMAGE_FILE_PATH)[0]}')
print(f'-- python-magic: {magic.from_file(IMAGE_FILE_PATH, mime=True)}')

print('')
print('===== 拡張子無し =====')
tmp = './dummy_image'
shutil.copy(IMAGE_FILE_PATH, tmp)
print(f'-- mimetypes: {mimetypes.guess_type(tmp)[0]}')
print(f'-- python-magic: {magic.from_file(tmp, mime=True)}')

print('')
print('===== 拡張子を .mp4 の偽装 =====')
tmp = './dummy_image.mp4'
shutil.copy(IMAGE_FILE_PATH, tmp)
print(f'-- mimetypes: {mimetypes.guess_type(tmp)[0]}')
print(f'-- python-magic: {magic.from_file(tmp, mime=True)}')
実行結果
$ python main.py 
===== .png =====
-- mimetypes: image/png
-- python-magic: image/png

===== 拡張子無し =====
-- mimetypes: None
-- python-magic: image/png

===== 拡張子を .mp4 の偽装 =====
-- mimetypes: video/mp4
-- python-magic: image/png
15
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
6