8

そのため、JSON ファイルをタブ区切りファイルに解析しようとしています。解析は正常に機能しているようで、すべてのデータが通過しています。出力ファイルで最も奇妙なことが起こっていますが。タブ区切り文字を使用するように指示し、出力ではタブを使用しますが、それでも一重引用符を保持しているようです。そして、なぜか頭にBをつけているようです。ヘッダーを手動で入力したところ、問題なく動作しましたが、データ自体の動作がおかしいです。これが私が得ている出力の例です。

id  created text    screen name name    latitude    longitude   place name  place type
b'1234567890'   b'Thu Mar 14 19:39:07 +0000 2013'   "b""I'm at Bank Of America (Wayne, MI) http://t.co/asdf"""  b'userid'   b'username' 42.28286837 -83.38487864    b'Bank Of America, Wayne'   b'poi'
b'1234567891'   b'Thu Mar 14 19:39:16 +0000 2013'   b'here is a sample tweet \xf0\x9f\x8f\x80 #notingoodhands'  b'userid2'  b'username2'

これが、データを書き出すために使用しているコードです。

out = open(filename, 'w')
   out.write('id\tcreated\ttext\tscreen name\tname\tlatitude\tlongitude\tplace name\tplace type')
   out.write('\n')
   rows = zip(ids, times, texts, screen_names, names, lats, lons, place_names, place_types)
   from csv import writer
   csv = writer(out, dialect='excel', delimiter = '\t')
   for row in rows:
       values = [(value.encode('utf-8') if hasattr(value, 'encode') else value) for value in row]
       csv.writerow(values)
   out.close()

これが問題です。utf-8ビットなしでこれを行い、そのまま出力した場合、フォーマットは完全に希望どおりになります。しかし、人々が特殊文字を入力すると、プログラムがクラッシュして処理できなくなります。

Traceback (most recent call last):
  File "tweets.py", line 34, in <module>
    csv.writerow(values)
  File "C:\Python33\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f3c0' in position 153: character maps to <undefined>

utf-8 ビットを追加すると、ここに表示される出力のタイプに変換されますが、これらすべての文字が出力に追加されます。誰もこれについて何か考えがありますか?

4

2 に答える 2

13

データを自分でエンコードしているため、Unicode ではなくバイト データをファイルに書き込んでいます。

呼び出しを完全に削除し、encodePython にこれを処理させます。UTF8 エンコーディングでファイルを開くと、残りは自動的に処理されます。

out = open(filename, 'w', encoding='utf8')

これは、csvモジュールのドキュメントに記載されています。

open()は読み取り用に CSV ファイルを開くために使用されるため、ファイルはデフォルトで、システムのデフォルト エンコーディングを使用して Unicode にデコードされます( を参照)locale.getpreferredencoding()。別のエンコーディングを使用してファイルをデコードするには、open の encoding 引数を使用します。

import csv
with open('some.csv', newline='', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
         print(row)

システムのデフォルト エンコーディング以外で書き込む場合も同様です。出力ファイルを開くときにエンコーディング引数を指定します。

于 2013-03-14T21:25:16.397 に答える
1

ここでは複数のことが起こっていますが、最初に、少し混乱を解消しましょう。

非 ASCII 文字を UTF-8 にエンコードすると、複数のバイトが得られます。たとえば、文字\xf0\x9f\x8f\x80UTF-8 です。しかし、それはまだ 1 文字であり、4 バイトを必要とする文字です。文字列をバイナリ ファイルに書き込んでから、そのファイルを UTF-8 互換ツール (メモ帳や TextEdit、またはUTF-8 対応のターミナル/シェル) で見ると、4 つではなくcat1 つが表示されます。ゴミキャラ。

2 つ目は、先頭に が追加されb'abc'た文字列ではなく、バイト文字列の表現です。は、引用符と同じように文字列の一部ではありません。breprabcb

最後に、Python 3 では、ファイルをテキスト モードで開いてからバイト文字列を書き込むことはできません。エンコーディングを使用してテキスト モードで開き、通常の Unicode 文字列を書き込むか、バイナリ モードで開き、エンコードされたバイト文字列を書き込みます。

于 2013-03-14T21:35:30.727 に答える