テキストファイルをPythonに読み込む必要があります。ファイルのエンコードは次のとおりです。
file -bi test.csv
text/plain; charset=us-ascii
これはサードパーティのファイルであり、毎日新しいファイルを取得するため、変更することは避けたいです。ファイルには、たとえばÖなどの非ASCII文字が含まれています。 pythonを使用して行を読む必要があり、非ASCII文字を含む行を無視する余裕があります。
私の問題は、Pythonでファイルを読み取ると、非ASCII文字が存在する行に到達するとUnicodeDecodeErrorが発生し、残りのファイルを読み取れないことです。
これを回避する方法はありますか。これを試してみると:
fileHandle = codecs.open("test.csv", encoding='utf-8');
try:
for line in companiesFile:
print(line, end="");
except UnicodeDecodeError:
pass;
次に、エラーに達するとforループが終了し、ファイルの残りを読み取ることができません。間違いの原因となっている行をスキップして続行します。可能であれば、入力ファイルに変更を加えません。
これを行う方法はありますか?どうもありがとうございました。
ファイルはUTF-8エンコードを使用していないようです。ファイルを開くときに正しいコーデックを使用することが重要です。
Youcantell open()
errors
キーワードを使用したデコードエラーの処理方法:
errorsは、エンコードおよびデコードエラーの処理方法を指定するオプションの文字列です。これはバイナリモードでは使用できません。
codecs.register_error()
に登録されているエラー処理名も有効ですが、さまざまな標準エラーハンドラが利用できます。標準名は次のとおりです。
'strict'
は、エンコードエラーがある場合にValueError
例外を発生させます。None
のデフォルト値は同じ効果があります。'ignore'
はエラーを無視します。エンコードエラーを無視すると、データが失われる可能性があることに注意してください。'replace'
は、不正なデータがある場所に置換マーカー(「?」など)を挿入します。'surrogateescape'
は、U + DC80からU + DCFFまでの範囲のUnicode Private Use Areaのコードポイントとして、不正なバイトを表します。これらのプライベートコードポイントは、データの書き込み時にsurrogateescape
エラーハンドラーが使用されると、同じバイトに戻されます。これは、未知のエンコーディングのファイルを処理するのに役立ちます。'xmlcharrefreplace'
は、ファイルへの書き込み時にのみサポートされます。エンコードでサポートされていない文字は、適切なXML文字参照&#nnn;
に置き換えられます。'backslashreplace'
(書き込み時のみサポート)は、サポートされていない文字をPythonのバックスラッシュ付きエスケープシーケンスに置き換えます。
'strict'
('ignore'
、'replace'
など)以外でファイルを開くと、例外が発生することなくファイルを読み取ることができます。
デコードは、テキスト行ごとではなく、バッファリングされたデータブロックごとに行われることに注意してください。行ごとにエラーを検出する必要がある場合は、surrogateescape
ハンドラーを使用して、サロゲート範囲内のコードポイントの各行の読み取りをテストします。
import re
_surrogates = re.compile(r"[\uDC80-\uDCFF]")
def detect_decoding_errors_line(l, _s=_surrogates.finditer):
"""Return decoding errors in a line of text
Works with text lines decoded with the surrogateescape
error handler.
Returns a list of (pos, byte) tuples
"""
# DC80 - DCFF encode bad bytes 80-FF
return [(m.start(), bytes([ord(m.group()) - 0xDC00]))
for m in _s(l)]
例えば。
with open("test.csv", encoding="utf8", errors="surrogateescape") as f:
for i, line in enumerate(f, 1):
errors = detect_decoding_errors_line(line)
if errors:
print(f"Found errors on line {i}:")
for (col, b) in errors:
print(f" {col + 1:2d}: {b[0]:02x}")
すべてのデコードエラーが正常に回復できるわけではないことを考慮してください。 UTF-8は小さなエラーに直面しても堅牢になるように設計されていますが、UTF-16やUTF-32などの他のマルチバイトエンコーディングは、ドロップまたは余分なバイトに対処できません。あります。上記の方法では、ファイルの残りの部分が1つの長い行として扱われます。ファイルが十分に大きい場合、「行」が十分に大きい場合、それはMemoryError
例外につながる可能性があります。