Wyciągam dane z dokumentu Google, przetwarzam je i zapisuję w pliku (który ostatecznie wkleję na stronie Wordpress).
Ma kilka symboli spoza ASCII. Jak przekonwertować je bezpiecznie na symbole, których można używać w źródle HTML?
Obecnie po drodze konwertuję wszystko na Unicode, łączę to wszystko w łańcuch Python, a następnie:
import codecs
f = codecs.open('out.txt', mode="w", encoding="iso-8859-1")
f.write(all_html.encode("iso-8859-1", "replace"))
W ostatnim wierszu występuje błąd kodowania:
UnicodeDecodeError: Kodek „ascii” nie może dekodować bajtu 0xa0 na pozycji 12286: porządek poza zakresem (128)
Częściowe rozwiązanie:
Ten Python działa bez błędu:
row = [unicode(x.strip()) if x is not None else u'' for x in row]
all_html = row[0] + "<br/>" + row[1]
f = open('out.txt', 'w')
f.write(all_html.encode("utf-8"))
Ale jeśli otworzę właściwy plik tekstowy, widzę wiele symboli, takich jak:
Qur’an
Może muszę pisać do czegoś innego niż plik tekstowy?
Odpowiedzi:
Zajmuj się wyłącznie obiektami Unicode w jak największym stopniu, dekodując je do obiektów Unicode, gdy je dostaniesz, i kodując je w razie potrzeby po wyjściu.
Jeśli Twój ciąg znaków jest w rzeczywistości obiektem Unicode, musisz go przekonwertować na obiekt łańcucha zakodowany w Unicode przed zapisaniem go w pliku:
Po ponownym odczytaniu tego pliku otrzymasz ciąg kodowany w Unicode, który możesz zdekodować do obiektu Unicode:
źródło
W Pythonie 2.6+ możesz użyć
io.open()
domyślnego ( wbudowanegoopen()
) w Python 3:Może być wygodniejsze, jeśli trzeba pisać tekst przyrostowo (nie trzeba dzwonić
unicode_text.encode(character_encoding)
wiele razy). W przeciwieństwie docodecs
modułu,io
moduł ma odpowiednią uniwersalną obsługę nowego wiersza.źródło
Obsługa ciągów znaków Unicode jest już ustandaryzowana w Pythonie 3.
Wystarczy otworzyć plik w utf-8
(32-bitowa konwersja utf-8 w Unicode na zmienną długość bajtu jest wykonywana automatycznie z pamięci do pliku).
źródło
Plik otwierany przez
codecs.open
to plik, który pobieraunicode
dane, koduje jeiso-8859-1
i zapisuje w pliku. Jednak to, co próbujesz napisać, nie jestunicode
; bierzeszunicode
i kodujesz wiso-8859-1
sobie . Tak właśnie działaunicode.encode
metoda, a wynikiem kodowania łańcucha znaków Unicode jest testowanie (str
typ).Powinieneś albo użyć normalnego
open()
i samodzielnie kodować Unicode, albo (zazwyczaj lepszy pomysł) użyćcodecs.open()
i nie kodować danych samodzielnie.źródło
Przedmowa: czy Twój widz będzie działał?
Upewnij się, że twoja przeglądarka / edytor / terminal (jakkolwiek wchodzisz w interakcję z plikiem zakodowanym w utf-8) może go odczytać. Jest to często problem w systemie Windows , na przykład w Notatniku.
W Python 2 użyj
open
zio
modułu (jest to to samo, co wbudowaneopen
w Python 3):Najlepsze praktyki, ogólnie rzecz biorąc, używaj
UTF-8
do zapisywania do plików (nie musimy nawet martwić się kolejnością bajtów z utf-8).utf-8 jest najnowocześniejszym i powszechnie używanym kodowaniem - działa we wszystkich przeglądarkach internetowych, w większości edytorów tekstu (sprawdź ustawienia, jeśli masz problemy) i na większości terminali / powłok.
W systemie Windows możesz spróbować,
utf-16le
jeśli jesteś ograniczony do wyświetlania wyników w Notatniku (lub innej ograniczonej przeglądarce).I po prostu otwórz go za pomocą menedżera kontekstu i wypisz swoje znaki Unicode:
Przykład użycia wielu znaków Unicode
Oto przykład, który próbuje zmapować każdy możliwy znak o szerokości do trzech bitów (4 to maksimum, ale byłoby to nieco daleko) od cyfrowej reprezentacji (w liczbach całkowitych) do zakodowanego wydruku, wraz z jego nazwą, jeśli możliwe (wstaw to do pliku o nazwie
uni.py
):Powinno to działać w kolejności około minuty i można wyświetlić plik danych, a jeśli przeglądarka plików może wyświetlać Unicode, zobaczysz go. Informacje o kategoriach można znaleźć tutaj . Na podstawie obliczeń możemy prawdopodobnie poprawić nasze wyniki, wykluczając kategorie Cn i Co, które nie mają z nimi żadnych symboli.
Wyświetli odwzorowanie szesnastkowe, kategorię , symbol (chyba że nie można uzyskać nazwy, więc prawdopodobnie znak kontrolny) i nazwę symbolu. na przykład
Polecam
less
na Unixie lub Cygwinie (nie drukuj / cat całego pliku na wyjście):np. wyświetli podobne do następujących wierszy, z których próbkowałem z niego przy użyciu Pythona 2 (Unicode 5.2):
Mój Python 3.5 z Anacondy ma Unicode 8.0, przypuszczam, że większość 3.
źródło
Jak wydrukować znaki Unicode do pliku:
Zapisz to w pliku: foo.py:
Uruchom i potokuj dane wyjściowe do pliku:
Otwórz tmp.txt i zajrzyj do środka, zobaczysz to:
W ten sposób zapisałeś Unicode e ze znacznikiem zaciemnienia w pliku.
źródło
Ten błąd pojawia się, gdy próbujesz zakodować ciąg znaków inny niż Unicode: próbuje go zdekodować, zakładając, że jest to zwykły ASCII. Istnieją dwie możliwości:
f.write(all_html)
zamiast tego..encode(...)
, najpierw próbuje go odkodować.źródło
W przypadku pisania w python3
W przypadku pisania w python2:
Aby uniknąć tego błędu, należy zakodować go w bajtach za pomocą kodeków „utf-8” w następujący sposób:
i dekoduj dane podczas odczytu przy użyciu kodeków „utf-8”:
A także, jeśli spróbujesz wykonać print na tym ciągu, automatycznie dekoduje przy użyciu takich kodeków „utf-8” jak ten
źródło