2016-06-28 24 views
6

Używam Pythona 3.5 i próbuję pobrać blok tekstu bajtowego, który może zawierać lub nie zawierać specjalnych chińskich znaków i wyprowadzić go do pliku. Działa dla wpisów, które nie zawierają chińskich znaków, ale łamie się, gdy robią. Chińskie znaki zawsze są imionami osób i zawsze są dodatkiem do angielskiej pisowni ich imienia. Tekst jest sformatowany JSON i musi zostać odkodowany, zanim będę mógł go załadować. Dekodowanie wydaje się przebiegać dobrze i nie powoduje żadnych błędów. Gdy próbuję i napisać dekodowany tekst do pliku daje mi się następujący komunikat o błędzie:Problem z dekodowaniem języka Python z chińskimi znakami

UnicodeEncodeError: 'charmap' codec can't encode characters in position 14-18: character maps to undefined

Oto przykład z surowych danych, które otrzymuję, zanim zrobię coś do niego:

b' "isBulkRecipient": "false",\r\n  "name": "Name in, English \xef' 
b'\xab\x62\xb6\xe2\x15\x8a\x8b\x8a\xee\xab\x89\xcf\xbc\x8a",\r\n 

Oto kod, który używam:

recipientData = json.loads(recipientContent.decode('utf-8', 'ignore')) 
recipientName = recipientData['signers'][0]['name'] 
pprint(recipientName) 
with open('envelope recipient list.csv', 'a', newline='') as fp: 
    a = csv.writer(fp, delimiter=',') 
    csvData = [[recipientName]] 
    a.writerows(csvData) 

recipientContent uzyskuje się z wywołania API. Nie muszę mieć chińskich znaków w pliku wyjściowym. Będę wdzięczny za jakąkolwiek radę!

Aktualizacja:

Robiłem kilka ręcznych obejścia dla każdego wpisu, który rozkłada i przyszedł inne wpisy, które nie zawierają chińskie znaki specjalne, ale miał je z innych języków, a przerwał program jako dobrze. Znaki specjalne są tylko w polu nazwy. A więc nazwa może brzmieć jak "Ałeks", gdzie jest mieszaniną postaci normalnych i specjalnych. Przed dekodowaniem ciągu znaków zawierającego te informacje mogę go wydrukować na ekranie i wygląda to tak: b'name": "A\xc5ex",\r\n

Ale po tym, jak ją odkodowuję w utf-8, spowoduje to błąd, jeśli spróbuję wyprowadzić to. Komunikat o błędzie: UnicodeEncodeError: 'charmap' codec can't encode character 'u0142' in position 2- character maps to -undefined-

Sprawdziłem, czym jest i jest to szczególna postać.

+0

Przykład ciąg nie wydają się być UTF-8 (ani wspólnej chińskiej wielobajtowych kodowania). Czy jesteś pewien, że jest kodowany w UTF-8 (lub nawet chiński)? – univerio

+0

należy sprawdzić "Content-Type". Jeśli jest to 'application/json; charset = utf-16', użyj 'utf-16'. Wartością domyślną dla 'application/json' jest' utf-8' –

+0

Nie jestem w 100% pewny, że jego utf-8, ponieważ usługa sieciowa pobierająca dane nie ma tego udokumentowanego bardzo dobrze, ale próbowałem kilku różne typy kodowania, w tym utf-16. Jestem pewien, że zawiera chińskie znaki. –

Odpowiedz

0

Ostrzeżenie: rozwiązanie shotgun naprzód

Zakładając, że po prostu chcesz pozbyć się wszystkich znaków obcego we wszystkich pliku (czyli nie są one ważne dla przyszłego przetwarzania wszystkich innych dziedzinach), można po prostu ignoruje wszystkie znaki spoza aSCII

recipientData = json.loads(recipientContent.decode('utf-8', 'ignore')) 

przez

recipientData = json.loads(recipientContent.decode('ascii', 'ignore')) 

jak to usunąć wszystkie non aSCII ch znaki przed dalszym przetwarzaniem.

nazwałem to rozwiązanie shotgun ponieważ może nie działać prawidłowo w pewnych okolicznościach:

  1. Oczywiście, jeśli potrzebne są spoza ASCII zachować do wykorzystania w przyszłości
  2. Jeśli b'\' lub b" znaków pojawia się na przykład z części postaci utf-16.
0

Pojawia się błąd podczas zapisywania do pliku.

W języku Python 3.x, gdy jesteś w trybie tekstowym (domyślnie) bez określania wartości encoding=, Python użyje kodowania najlepiej pasującego do ustawień regionalnych lub językowych.

Jeśli korzystasz z systemu Windows, użyje kodeku charmap do mapowania na kodowanie języka.

Chociaż można po prostu pisać bajty bezpośrednio do pliku, robisz to, co trzeba, najpierw dekodując je. Jak powiedzieli inni, powinieneś naprawdę dekodować za pomocą kodowania określonego przez serwer WWW. Możesz także użyć modułu Python Request, który robi to za ciebie. (Twój przykład nie dekoduje jako UTF-8, więc zakładam, że twój przykład jest nieprawidłowy)

Aby rozwiązać swój bezpośredni błąd, po prostu przeprowadź encoding do open(), który obsługuje znaki, które masz w swoich danych. Unicode w kodowaniu UTF-8 jest oczywistym wyborem. Dlatego należy zmienić swój kod do odczytu:

with open('envelope recipient list.csv', 'a', encoding='utf-8', newline='') as fp: 
0

Dodaj tę linię do kodu:

from __future__ import unicode_literals 
+0

Dlaczego ta pomoc? –