Frage

Nehmen wir an, Sie möchten eine Reihe von Dateien irgendwo speichern, beispielsweise in BLOBs.Nehmen wir an, Sie möchten diese Dateien über eine Webseite verteilen und den Client automatisch die richtige Anwendung/den richtigen Viewer öffnen lassen.

Annahme:Der Browser erkennt anhand des Mime-Type-Headers (Content-Type?) in der HTTP-Antwort, welche Anwendung/welcher Viewer verwendet werden soll.

Basierend auf dieser Annahme möchten Sie zusätzlich zu den Bytes der Datei auch den MIME-Typ speichern.

Wie finden Sie den MIME-Typ einer Datei?Ich verwende derzeit einen Mac, aber das sollte auch unter Windows funktionieren.

Fügt der Browser diese Informationen hinzu, wenn er die Datei auf der Webseite veröffentlicht?

Gibt es eine übersichtliche Python-Bibliothek, um diese Informationen zu finden?Ein WebService oder (noch besser) eine herunterladbare Datenbank?

War es hilfreich?

Lösung

Die von toivotuo vorgeschlagene Python-Magic-Methode ist veraltet. Python-Magie Der aktuelle Trunk befindet sich bei Github und basierend auf der dortigen Readme-Datei wird das Finden des MIME-Typs wie folgt durchgeführt.

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

Andere Tipps

Der Mimetypes-Modul in der Standardbibliothek ermittelt/errät den MIME-Typ anhand einer Dateierweiterung.

Wenn Benutzer Dateien hochladen, enthält der HTTP-Beitrag neben den Daten auch den MIME-Typ der Datei.Django stellt diese Daten beispielsweise als Attribut des zur Verfügung HochgeladeneDatei Objekt.

Zuverlässiger als die Verwendung der Mimetypes-Bibliothek wäre die Verwendung des Pakets python-magic.

import magic
m = magic.open(magic.MAGIC_MIME)
m.load()
m.file("/tmp/document.pdf")

Dies wäre äquivalent zur Verwendung von Datei(1).

Auf Django könnte man auch sicherstellen, dass der MIME-Typ mit dem von UploadedFile.content_type übereinstimmt.

Das scheint sehr einfach zu sein

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

Siehe Alter Beitrag

Es gibt 3 verschiedene Bibliotheken, die libmagic umschließen.

2 davon sind auf Pypi verfügbar (damit die Pip-Installation funktioniert):

  • filemagic
  • Python-Magie

Und ein anderes, ähnlich wie python-magic, ist direkt in den neuesten libmagic-Quellen verfügbar, und es ist das, was Sie wahrscheinlich in Ihrer Linux-Distribution haben.

In Debian handelt es sich um das Paket python-magic, das verwendet wird, wie toivotuo sagte, und es ist nicht veraltet, wie Simon Zimmermann sagte (IMHO).

Es scheint mir eine andere Einstellung zu sein (vom ursprünglichen Autor von libmagic).

Schade, dass es nicht direkt auf Pypi verfügbar ist.

in Python 2.6:

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

Sie haben nicht angegeben, welchen Webserver Sie verwenden, aber Apache hat ein nettes kleines Modul namens Pantomime-Magie anhand dessen es den Typ einer Datei ermittelt, wenn es dazu aufgefordert wird.Es liest einen Teil des Inhalts der Datei und versucht anhand der gefundenen Zeichen herauszufinden, um welchen Typ es sich handelt.Und wie Dave Webb erwähnt Die MimeTypes-Modul unter Python wird funktionieren, vorausgesetzt, eine Erweiterung ist praktisch.

Wenn Sie auf einem UNIX-Rechner sitzen, können Sie alternativ auch verwenden sys.popen('file -i ' + fileName, mode='r') um den MIME-Typ zu erfassen.Windows sollte einen entsprechenden Befehl haben, aber ich bin mir nicht sicher, was das ist.

Die Methode von @toivotuo funktionierte für mich unter Python3 am besten und zuverlässigsten.Mein Ziel war es, gzip-Dateien zu identifizieren, die keine zuverlässige .gz-Erweiterung haben.Ich habe Python3-Magic installiert.

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

Für eine gzip-Datei wird Folgendes zurückgegeben:application/gzip;Zeichensatz=binär

für eine entpackte TXT-Datei (Iostat-Daten):Text/einfach;charset=us-ascii

für eine TAR-Datei:application/x-tar;Zeichensatz=binär

für eine bz2-Datei:application/x-bzip2;Zeichensatz=binär

und zu guter Letzt für mich eine .zip-Datei:Anwendung/zip;Zeichensatz=binär

In Python 3.x und Webapp mit URL zur Datei, die keine Erweiterung oder eine gefälschte Erweiterung haben darf.Sie sollten Python-Magic mit installieren

pip3 install python-magic

Für Mac OS X sollten Sie auch libmagic mit installieren

brew install libmagic

Code-Auszug

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)

Alternativ könnten Sie eine Größe in den Lesevorgang eingeben

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)

Aktualisierung 2017

Sie müssen nicht zu Github gehen, es ist auf PyPi unter einem anderen Namen:

pip3 install --user python-magic
# or:
sudo apt install python3-magic  # Ubuntu distro package

Der Code kann auch vereinfacht werden:

>>> import magic

>>> magic.from_file('/tmp/img_3304.jpg', mime=True)
'image/jpeg'

Python-Bindungen an libmagic

Die unterschiedlichen Antworten zu diesem Thema sind sehr verwirrend, daher hoffe ich, mit diesem Überblick über die verschiedenen Bindungen von libmagic etwas mehr Klarheit zu schaffen.Zuvor gab Mammadori eine kurze Antwort Auflistung der verfügbaren Option.

libmagic

Bei der Bestimmung eines Datei-MIME-Typs wird einfach das Tool der Wahl aufgerufen file und sein Backend heißt libmagic.(Siehe die Projekthomepage.) Das Projekt wird in einem privaten CVS-Repository entwickelt, es gibt jedoch ein schreibgeschützter Git-Spiegel auf Github.

Nun verfügt dieses Tool, das Sie benötigen, wenn Sie eine der libmagic-Bindungen mit Python verwenden möchten, bereits über eigene Python-Bindungen namens file-magic.Es gibt nicht viel spezielle Dokumentation für sie, aber Sie können jederzeit einen Blick auf die Manpage der C-Bibliothek werfen: man libmagic.Die grundlegende Verwendung wird im beschrieben Readme-Datei:

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)

Darüber hinaus können Sie die Bibliothek auch nutzen, indem Sie eine erstellen Magic Objekt verwenden magic.open(flags) wie in der gezeigt Beispieldatei.

Beide toivotuo und ewr2san verwenden diese file-magic Bindungen im Lieferumfang enthalten file Werkzeug.Sie gehen fälschlicherweise davon aus, dass sie das verwenden python-magic Paket. Dies scheint darauf hinzudeuten, dass beides der Fall ist file Und python-magic installiert sind, das Python-Modul magic bezieht sich auf ersteres.

Python-Magie

Dies ist die Bibliothek, über die Simon Zimmermann spricht seine Antwort und die auch bei beschäftigt ist Claude COULOMBE sowie Gringo Suave.

filemagic

Notiz:Dieses Projekt wurde zuletzt im Jahr 2013 aktualisiert!

Da diese Bibliothek auf derselben C-API basiert, weist sie eine gewisse Ähnlichkeit mit auf file-magic enthalten libmagic.Es wird nur von erwähnt mammadori und keine andere Antwort verwendet es.

Das Mimetypes-Modul erkennt einen Dateityp lediglich anhand der Dateierweiterung.Wenn Sie versuchen, einen Dateityp ohne Erweiterung wiederherzustellen, funktionieren die Mimetypes nicht.

Ich habe viele Beispiele ausprobiert, aber mit Django mutagen spielt sich gut.

Beispiel für die Überprüfung, ob Dateien vorhanden sind mp3

from mutagen.mp3 import MP3, HeaderNotFoundError  

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

Der Nachteil besteht darin, dass Sie nur begrenzte Möglichkeiten zur Überprüfung von Dateitypen haben. Dies ist jedoch eine großartige Möglichkeit, wenn Sie nicht nur den Dateityp überprüfen, sondern auch auf zusätzliche Informationen zugreifen möchten.

Das ist vielleicht schon alt, aber warum nicht UploadedFile.content_type direkt aus Django verwenden?Ist nicht das Gleiche?(https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type)

Für Daten von Byte -Array -Typ können Sie Magic.from_Buffer (_byte_array, mime = true) verwenden.

Ich probiere zuerst die Mimetypes-Bibliothek aus.Wenn es nicht funktioniert, verwende ich stattdessen die Python-Magic-Bibliothek.

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

Sie können verwenden imghdr Python-Modul.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top