Запись текста Unicode в текстовый файл?
я вытаскиваю данные из документа Google, обрабатываю его и записываю в файл (который в конечном итоге я вставлю на страницу Wordpress).
Он имеет некоторые символы, отличные от ASCII. Как я могу безопасно конвертировать их в символы, которые можно использовать в HTML-источнике?
В настоящее время я конвертирую все в Unicode по пути, объединяя все это вместе в строку Python, а затем делаю:
import codecs
f = codecs.open('out.txt', mode="w", encoding="iso-8859-1")
f.write(all_html.encode("iso-8859-1", "replace"))
есть ошибка кодирования в последней строке:
UnicodeDecodeError: 'в кодировке ASCII' кодек не может декодировать байт 0xa0 в положении
12286: порядковый номер не в диапазон(128)
частичное решение:
этот Python работает без ошибок:
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")
но тогда, если я открою фактический текстовый файл, я вижу много символов, таких как:
Qur’an
может быть, мне нужно написать что-то другое, чем текстовый файл?
7 ответов:
Как можно больше занимайтесь исключительно объектами unicode, декодируя вещи в объекты unicode при их первом получении и кодируя их по мере необходимости на выходе.
Если ваша строка на самом деле является объектом unicode, вам необходимо преобразовать ее в объект строки в кодировке unicode перед записью в файл:
foo = u'Δ, Й, ק, م, ๗, あ, 叶, 葉, and 말.' f = open('test', 'w') f.write(foo.encode('utf8')) f.close()при повторном чтении этого файла вы получите строку в кодировке unicode, которую можно декодировать в объект unicode:
f = file('test', 'r') print f.read().decode('utf8')
в Python 2.6+, вы могли бы использовать
io.open()это значение по умолчанию (builtinopen()) на Python 3:import io with io.open(filename, 'w', encoding=character_encoding) as file: file.write(unicode_text)это может быть более удобно, если вам нужно писать текст постепенно (вам не нужно звонить
unicode_text.encode(character_encoding)несколько раз). В отличие отcodecsмодульioмодуль имеет соответствующую универсальную поддержку новых строк.
файл
codecs.open- это файл, который занимаетunicodeданные, кодирует их вiso-8859-1и записывает его в файл. Однако то, что вы пытаетесь написать, это неunicode, тыunicodeи закодировать его вiso-8859-1сами. Вот что такоеunicode.encodeметод делает, и результатом кодирования строки unicode является bytestring (astrтип.)вы должны либо использовать обычный тег
open()и закодировать Юникод самостоятельно, или (как правило, лучшая идея) использоватьcodecs.open()и не зашифровать сами данные.
предисловие: будет ли ваш зритель работать?
убедитесь, что ваш просмотрщик/редактор/терминал (однако вы взаимодействуете с вашим файлом в кодировке utf-8) может прочитать файл. Это часто проблема на Windows, например, блокнот.
запись текста Unicode в текстовый файл?
в Python 2, Используйте
openСioмодуль (это то же самое, что встроенныйopenв Python 3):import ioлучшие практика, в общем, используйте
UTF-8для записи в файлы (нам даже не нужно беспокоиться о порядке байтов с utf-8).encoding = 'utf-8'utf-8-это самая современная и универсальная кодировка-она работает во всех веб-браузерах, большинстве текстовых редакторов (см. настройки, если у вас есть проблемы) и большинстве терминалов/оболочек.
на Windows, вы можете попробовать
utf-16leесли вы ограничены просмотром вывода в блокноте (или другом ограниченном средстве просмотра).encoding = 'utf-16le' # sorry, Windows users... :(и просто откройте его с помощью контекстного менеджера и напишите свои символы юникода:
with io.open(filename, 'w', encoding=encoding) as f: f.write(unicode_object)пример использования многие символы Unicode
вот пример, который пытается сопоставить каждый возможный символ шириной до трех битов (4-это максимум, но это будет немного далеко) от цифрового представления (в целых числах) до закодированного вывода для печати вместе с его именем, если это возможно (поместите это в файл с именем
uni.py):from __future__ import print_function import io from unicodedata import name, category from curses.ascii import controlnames from collections import Counter try: # use these if Python 2 unicode_chr, range = unichr, xrange except NameError: # Python 3 unicode_chr = chr exclude_categories = set(('Co', 'Cn')) counts = Counter() control_names = dict(enumerate(controlnames)) with io.open('unidata', 'w', encoding='utf-8') as f: for x in range((2**8)**3): try: char = unicode_chr(x) except ValueError: continue # can't map to unicode, try next x cat = category(char) counts.update((cat,)) if cat in exclude_categories: continue # get rid of noise & greatly shorten result file try: uname = name(char) except ValueError: # probably control character, don't use actual uname = control_names.get(x, '') f.write(u'{0:>6x} {1} {2}\n'.format(x, cat, uname)) else: f.write(u'{0:>6x} {1} {2} {3}\n'.format(x, cat, char, uname)) # may as well describe the types we logged. for cat, count in counts.items(): print('{0} chars of category, {1}'.format(count, cat))это должно выполняться в порядке около минуты, и вы можете просмотреть файл данных, и если ваш просмотрщик файлов может отображать unicode, вы увидите его. Информацию о категориях можно найти здесь. Основываясь на подсчетах, мы, вероятно, можем улучшить наши результаты, исключив категории Cn и Co, которые не имеют связанных с ними символов.
$ python uni.pyон будет отображать шестнадцатеричное отображение, категория, символ (если только не может получить имя, поэтому, вероятно, управляющий символ) и имя о символе. например,
рекомендую
lessв Unix или Cygwin (не печатайте / cat весь файл на выходе):$ less unidataнапример, будет отображаться аналогично следующим строкам, которые я выбрал из него с помощью Python 2 (unicode 5.2):
0 Cc NUL 20 Zs SPACE 21 Po ! EXCLAMATION MARK b6 So ¶ PILCROW SIGN d0 Lu Ð LATIN CAPITAL LETTER ETH e59 Nd ๙ THAI DIGIT NINE 2887 So ⢇ BRAILLE PATTERN DOTS-1238 bc13 Lo 밓 HANGUL SYLLABLE MIH ffeb Sm → HALFWIDTH RIGHTWARDS ARROWмой Python 3.5 от Anaconda имеет unicode 8.0,я бы предположил, что большинство 3-х.
обработка строк Unicode стандартизирована в Python 3.
- Char хранятся в Unicode
вам нужно только открыть файл в utf-8
out1 = "(嘉南大圳 ㄐㄧㄚ ㄋㄢˊ ㄉㄚˋ ㄗㄨㄣˋ )" fobj = open("t1.txt", "w", encoding="utf-8") fobj.write(out1) fobj.close()
как печатать символы юникода в файл:
сохраните это в файл: foo.py:
#!/usr/bin/python -tt # -*- coding: utf-8 -*- import codecs import sys UTF8Writer = codecs.getwriter('utf8') sys.stdout = UTF8Writer(sys.stdout) print(u'e with obfuscation: é')запустите его и передайте вывод в файл:
python foo.py > tmp.txtоткрыть tmp.TXT и посмотрите внутрь, вы видите это:
el@apollo:~$ cat tmp.txt e with obfuscation: éтаким образом, вы сохранили unicode e с меткой обфускации на нем в файл.
эта ошибка возникает при попытке кодировать строку, отличную от unicode: она пытается декодировать ее, предполагая, что она находится в обычном ASCII. Есть две возможности:
- вы кодируете его в bytestring, но потому, что вы использовали кодеки.open, метод write ожидает объект unicode. Поэтому вы кодируете его, и он пытается декодировать его снова. Попробуйте:.
- all_html на самом деле не является объектом unicode. Когда вы делаете
.encode(...), Он сначала пытается расшифровать оно.
Comments