写Unicode文本到文本文件?

我从Google文档中提取数据,处理数据,并将其写入文件(最终我将粘贴到Wordpress页面中)。

它有一些非ASCII符号。 如何将这些安全地转换为可用于HTML源代码的符号?

目前我正在将所有内容都转换为Unicode,并将它们连接到Pythonstring中,然后执行下列操作:

import codecs f = codecs.open('out.txt', mode="w", encoding="iso-8859-1") f.write(all_html.encode("iso-8859-1", "replace")) 

最后一行有一个编码错误:

UnicodeDecodeError:'ascii'编解码器无法解码位于12286的字节0xa0:序号不在范围内(128)

部分解决scheme:

这个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 

也许我需要写一个文本文件以外的东西?

当你第一次得到它们并在必要的时候编码它们的时候,把事情解码成unicode对象,尽可能地处理unicode对象。

如果您的string实际上是一个unicode对象,则在将其写入文件之前,需要将其转换为unicode编码的string对象:

 foo = u'Δ, Й, ק, ‎ م, ๗, あ, 叶, 葉, and 말.' f = open('test', 'w') f.write(foo.encode('utf8')) f.close() 

当您再次读取该文件时,您将得到一个unicode编码的string,您可以将其解码为一个unicode对象:

 f = file('test', 'r') print f.read().decode('utf8') 

在Python 2.6+中,你可以在Python 3上使用io.open() ,它是默认的( builtin open() ):

 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方法所做的,编码一个unicodestring的结果是一个string(一个strtypes)。

你应该使用普通的open()自己编码unicode,或者(通常是一个更好的主意)使用codecs.open()不是自己编码数据。

前言:你的观众会工作吗?

确保你的浏览器/编辑器/terminal(不pipe你是否与utf-8编码文件交互)可以读取文件。 在Windows上这经常是一个问题,例如记事本。

写Unicode文本到文本文件?

在Python 2中,使用io模块中的open与Python 3中open的内build相同):

 import io 

一般来说,最好的做法是使用UTF-8写入文件(我们甚至不用担心utf-8的字节顺序)。

 encoding = 'utf-8' 

utf-8是最现代化和通用的编码方式,适用于所有networking浏览器,大多数文本编辑器(如果您有问题,请参阅您的设置)和大多数terminal/shell。

在Windows上,如果仅限于在记事本(或另一个有限的查看器)中查看输出,则可以尝试使用utf-16le

 encoding = 'utf-16le' # sorry, Windows users... :( 

只要用上下文pipe理器打开它,写出你的Unicode字符:

 with io.open(filename, 'w', encoding=encoding) as f: f.write(unicode_object) 

使用许多Unicode字符的示例

下面是一个例子,试图将每个可能的字符从数字表示(整数)映射到一个编码的可打印输出,以及它的名字if(最大3位,但是这将会有点远)可能的(把它放到一个名为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,你会看到它。 有关类别的信息可以在这里find。 根据计数,我们可以通过排除没有与它们相关联的符号的Cn和Co类别来改善我们的结果。

 $ python uni.py 

它将显示hex映射, 类别 ,符号(除非不能得到名称,所以可能是一个控制字符)和符号的名称。 例如

我build议在Unix或Cygwin上less用一些(不要将整个文件打印到输出中):

 $ 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 

我从Anaconda的Python 3.5有Unicode 8.0,我会假设大多数3的会。

Unicodestring处理在Python 3中被标准化。

  1. 字符存储在Unicode中
  2. 您只需要在utf-8中打开文件

     out1 = "(嘉南大圳 ㄐㄧㄚ ㄋㄢˊ ㄉㄚˋ ㄗㄨㄣˋ )" fobj = open("t1.txt", "w", encoding="utf-8") fobj.write(out1) fobj.close() 

如何将unicode字符打印到文件中:

保存到文件: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上的一个模糊标记到一个文件。

当您尝试对非Unicodestring进行编码时,会出现此错误:它会尝试对其进行解码,假定它是纯ASCIIstring。 有两种可能性:

  1. 您将它编码为一个字节串,但是因为您已经使用了codecs.open,所以write方法需要一个unicode对象。 所以你编码它,并试图再次解码。 试试: f.write(all_html)
  2. 实际上,all_html并不是一个unicode对象。 当你.encode(...) ,它首先尝试解码它。