0

Ubuntu 12 x64 で Python 2.7.3 を使用しています。

ファイルシステムのフォルダーに約 200,000 個のファイルがあります。一部のファイルのファイル名には、HTML でエンコードされ、エスケープされた文字が含まれています。これは、ファイルが最初に Web サイトからダウンロードされたためです。以下に例を示します。

Jamaica%2008%20114.jpg
thai_trip_%E8%B0%83%E6%95%B4%E5%A4%A7%E5%B0%8F%20RAY_5313.jpg

フォルダーを通過し、ファイル名にエンコードされた文字を含むすべてのファイルの名前を変更する単純な Python スクリプトを作成しました。新しいファイル名は、ファイル名を構成する文字列を単純にデコードすることによって取得されます。

スクリプトはほとんどのファイルで機能しますが、一部のファイルでは Python がチョークして次のエラーを吐き出します。

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 11: ordinal not in range(128)
Traceback (most recent call last):
  File "./download.py", line 53, in downloadGalleries
    numDownloaded = downloadGallery(opener, galleryLink)
  File "./download.py", line 75, in downloadGallery
    filePathPrefix = getFilePath(content)
  File "./download.py", line 90, in getFilePath
    return cleanupString(match.group(1).strip()) + '/' + cleanupString(match.group(2).strip())
  File "/home/abc/XYZ/common.py", line 22, in cleanupString
    return HTMLParser.HTMLParser().unescape(string)
  File "/usr/lib/python2.7/HTMLParser.py", line 472, in unescape
    return re.sub(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));", replaceEntities, s)
  File "/usr/lib/python2.7/re.py", line 151, in sub
    return _compile(pattern, flags).sub(repl, string, count)

私の cleanupString 関数の内容は次のとおりです。

def cleanupString(string):
    string = urllib2.unquote(string)

    return HTMLParser.HTMLParser().unescape(string)

cleanupString 関数を呼び出すコードのスニペットを次に示します (このコードは上記のトレースバックのコードとは異なりますが、同じエラーが発生します)。

rootFolder = sys.argv[1]
pattern = r'.*\.jpg\s*$|.*\.jpeg\s*$'
reobj = re.compile(pattern, re.IGNORECASE)
imgs = []

for root, dirs, files in os.walk(rootFolder):
    for filename in files:
        foundFile = os.path.join(root, filename)

        if reobj.match(foundFile):
            imgs.append(foundFile)

for img in imgs :
    print 'Checking file: ' + img
    newImg = cleanupString(img) #Code blows up here for some files

このエラーを回避する方法を誰かに教えてもらえますか? 私はすでに追加しようとしました

# -*- coding: utf-8 -*-

スクリプトの先頭に移動しますが、効果はありません。

ありがとう。

4

2 に答える 2

6

ファイル名は、Unicode 文字を表す UTF-8 バイトを含むバイト文字列です。HTML パーサーは通常、バイト文字列ではなく Unicode データで動作します。特にアンパサンド エスケープが発生した場合は、Python が自動的に値をデコードしようとしますが、デフォルトではASCIIそのデコードに使用されます。UTF-8 データには ASCII 範囲外のバイトが含まれているため、これは失敗します。

文字列を明示的に Unicode オブジェクトにデコードする必要があります。

def cleanupString(string):
    string = urllib2.unquote(string).decode('utf8')

    return HTMLParser.HTMLParser().unescape(string)

次の問題は、ファイル名が Unicode になっていることですが、これらのファイル名を扱うにはファイルシステムに何らかのエンコードが必要です。そのエンコーディングが何であるかを確認できsys.getfilesystemencoding()ます; これを使用して、ファイル名を再エンコードします。

def cleanupString(string):
    string = urllib2.unquote(string).decode('utf8')

    return HTMLParser.HTMLParser().unescape(string).encode(sys.getfilesystemencoding())

Python が Unicode をどのように扱うかについては、Unicode HOWTOを参照してください。

于 2012-09-27T16:46:41.290 に答える
0

この問題にぶつかっているようです。ファイル名に ASCII 以外の文字が追加されるため、unescapeandを呼び出す順序を逆にしてみますが、問題が解決しない場合があります。unquoteunquote

窒息している実際のファイル名は何ですか?

于 2012-09-27T16:46:00.370 に答える