4

過去 2 日間、私は自分の問題の解決策を見つけるためにインターネットをスキャンしてきました。さまざまなファイルのフォルダーがあります。彼らはファイルタイプの賭けを実行します。存在する場合、各ファイルからメタデータを読み取る python スクリプトを作成しようとしています。その目的は、最終的にデータをファイルに出力して、別のプログラムのメタデータ抽出と比較することです。

ディレクトリ内のごく少数のファイルで機能する例をいくつか見つけました。私が見つけたすべての方法は、ストレージ コンテナ オブジェクトを開くことを扱っています。私は Python を初めて使用し、ストレージ コンテナー オブジェクトが何であるかわかりません。使用しようとすると、ほとんどのファイルがエラーになることを知っています

pythoncom.StgOpenStorage(<File Name>, None, flags)

実際に機能するいくつかのものを使用して、タイトル、件名、作成者、作成済みなどの主要なメタデータ タグを取得できます。

メタデータにアクセスするためのストレージ コンテナー以外の方法を知っている人はいますか? また、別の言語でこれを行う簡単な方法があれば、ぜひ提案してください。

ありがとう

4

5 に答える 5

13

Shell com オブジェクトを使用して、エクスプローラーに表示されるメタデータを取得できます。

import win32com.client
sh=win32com.client.gencache.EnsureDispatch('Shell.Application',0)
ns = sh.NameSpace(r'm:\music\Aerosmith\Classics Live!')
colnum = 0
columns = []
while True:
    colname=ns.GetDetailsOf(None, colnum)
    if not colname:
        break
    columns.append(colname)
    colnum += 1

for item in ns.Items():
    print (item.Path)
    for colnum in range(len(columns)):
        colval=ns.GetDetailsOf(item, colnum)
        if colval:
            print('\t', columns[colnum], colval)
于 2012-09-22T07:45:26.233 に答える
4

上記の回答を組み合わせて明確にする試みとして、私自身の回答を書くことにしました(これは私の問題を解決するのに大いに役立ちました)。

この問題には2つのアプローチがあると思います。

状況 1: ファイルに含まれるメタデータ (関心のあるメタデータ) がわかっている場合。

この場合、関心のあるメタデータを含む文字列のリストがあるとします。ここでは、これらのタグが正しいと仮定します (つまり、.txt ファイルのピクセル数には関心がありません)。

metadata = ['Name', 'Size', 'Item type', 'Date modified', 'Date created']

ここで、Greedo と Roger Upole によって提供されたコードを使用して、ファイルのフル パスと名前を個別に受け取り、対象のメタデータを含む辞書を返す関数を作成しました。

def get_file_metadata(path, filename, metadata):
    # Path shouldn't end with backslash, i.e. "E:\Images\Paris"
    # filename must include extension, i.e. "PID manual.pdf"
    # Returns dictionary containing all file metadata.
    sh = win32com.client.gencache.EnsureDispatch('Shell.Application', 0)
    ns = sh.NameSpace(path)

    # Enumeration is necessary because ns.GetDetailsOf only accepts an integer as 2nd argument
    file_metadata = dict()
    item = ns.ParseName(str(filename))
    for ind, attribute in enumerate(metadata):
        attr_value = ns.GetDetailsOf(item, ind)
        if attr_value:
            file_metadata[attribute] = attr_value

    return file_metadata

# *Note: you must know the total path to the file.*
# Example usage:
if __name__ == '__main__':
    folder = 'E:\Docs\BMW'
    filename = 'BMW series 1 owners manual.pdf'
    metadata = ['Name', 'Size', 'Item type', 'Date modified', 'Date created']
    print(get_file_metadata(folder, filename, metadata))

結果:

{'Name': 'BMW series 1 owners manual.pdf', 'Size': '11.4 MB', 'Item type': 'Foxit Reader PDF Document', 'Date modified': '8/30/2020 11:10 PM', 'Date created': '8/30/2020 11:10 PM'}

ファイルを作成したばかりで、Foxit PDFリーダーをメインのPDFリーダーとして使用しているため、これは正しいです。したがって、この関数はディクショナリを返します。キーはメタデータ タグであり、値は指定されたファイルのそれらのタグの値です。

状況 2: ファイルに含まれるメタデータがわからない

これは、特に最適性の点で、やや厳しい状況です。Roger Upole によって提案されたコードを分析したところ、基本的に、彼はNoneファイルのメタデータを読み取ろうとし、その結果、考えられるすべてのメタデータ タグのリストを取得しました。したがって、このリストをハードコピーしてからすべてのタグを読み取ろうとする方が簡単かもしれないと考えました。そうすれば、完了したら、ファイルが実際に持っているすべてのタグを含む辞書ができます。

私が考えているすべてのメタデータタグをコピーして、ファイルからすべてのタグを取得しようとするだけです。基本的に、Python リストのこの宣言をコピーして、上記のコードを使用します (メタデータをこの新しいリストに置き換えます)。

metadata = ['Name', 'Size', 'Item type', 'Date modified', 'Date created', 'Date accessed', 'Attributes', 'Offline status', 'Availability', 'Perceived type', 'Owner', 'Kind', 'Date taken', 'Contributing artists', 'Album', 'Year', 'Genre', 'Conductors', 'Tags', 'Rating', 'Authors', 'Title', 'Subject', 'Categories', 'Comments', 'Copyright', '#', 'Length', 'Bit rate', 'Protected', 'Camera model', 'Dimensions', 'Camera maker', 'Company', 'File description', 'Masters keywords', 'Masters keywords']

これは素晴らしい解決策ではないと思いますが、一方で、このリストをグローバル変数として保持し、すべての関数呼び出しに渡す必要なく使用できます。完全を期すために、この新しいメタデータ リストを使用した前の関数の出力を次に示します。

{'Name': 'BMW series 1 owners manual.pdf', 'Size': '11.4 MB', 'Item type': 'Foxit Reader PDF Document', 'Date modified': '8/30/2020 11:10 PM', 'Date created': '8/30/2020 11:10 PM', 'Date accessed': '8/30/2020 11:10 PM', 'Attributes': 'A', 'Perceived type': 'Unspecified', 'Owner': 'KEMALS-ASPIRE-E\\kemal', 'Kind': 'Document', 'Rating': 'Unrated'}

ご覧のとおり、返されたディクショナリには、ファイルに含まれるすべてのメタデータが含まれています。これが機能する理由は、if ステートメントのためです。

if attribute_value:

つまり、属性が と等しいときはいつでもNone、返される辞書に追加されません。

多くのファイルを処理する場合は、リストを毎回関数に渡すのではなく、グローバル/静的変数として宣言する方がよいことを強調しておきます。

于 2020-08-30T21:40:25.900 に答える
2

問題は、Windows がファイル メタデータを格納する方法が 2 つあることです。使用しているアプローチは、COM アプリケーションによって作成されたファイルに適しています。このデータは、ファイル自体の中に含まれています。ただし、NTFS5 の導入により、どのファイルにも代替データ ストリームの一部としてメタデータを含めることができます。したがって、成功するファイルは COM アプリで作成されたファイルであり、失敗するファイルはそうでない可能性があります。

COM アプリで作成されたファイルを処理するための、おそらくより堅牢な方法を次に示します: Get document summary information from any file

代替データ ストリームを使用すると、それらを直接読み取ることができます。

meta = open('myfile.ext:StreamName').read()

更新:さて、ファイルのメタデータではなくドキュメントのメタデータを求めていたので、これは関係ないと思います。質問の明確さは、どのような違いを生むことができます :|

これを試してください: Pythonでオフィスファイルの作成者を取得するには?

于 2012-09-21T04:55:55.107 に答える