Запись текста 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 


может быть, мне нужно написать что-то другое, чем текстовый файл?

791   7  

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() это значение по умолчанию (builtin open()) на 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 (a str тип.)

вы должны либо использовать обычный тег 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.

  1. Char хранятся в Unicode
  2. вам нужно только открыть файл в 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. Есть две возможности:

  1. вы кодируете его в bytestring, но потому, что вы использовали кодеки.open, метод write ожидает объект unicode. Поэтому вы кодируете его, и он пытается декодировать его снова. Попробуйте:.
  2. all_html на самом деле не является объектом unicode. Когда вы делаете .encode(...), Он сначала пытается расшифровать оно.

Comments

    Ничего не найдено.