python 在html中显示unicode
我正在写一个脚本,把我的链接和标题从Chrome导出到HTML文件中。
Chrome的书签是以JSON格式存储的,使用UTF编码。
有些标题是俄语的,所以它们的存储方式是这样的:
"name": "\u0425\u0430\u0431\u0440\ ..."
import codecs
f = codecs.open("chrome.json","r", "utf-8")
data = f.readlines()
urls = [] # for links
names = [] # for link titles
ind = 0
for i in data:
if i.find('"url":') != -1:
urls.append(i.split('"')[3])
names.append(data[ind-2].split('"')[3])
ind += 1
fw = codecs.open("chrome.html","w","utf-8")
fw.write("<html><body>\n")
for n in names:
fw.write(n + '<br>')
# print type(n) # this will return <type 'unicode'> for each url!
fw.write("</body></html>")
现在,在chrome.html中,我看到的内容显示为 \u0425\u0430\u0431...
我该如何把它们转换回俄语呢?
我使用的是Python 2.5。
**编辑:解决了!**
s = '\u041f\u0440\u0438\u0432\u0435\u0442 world!'
type(s)
<type 'str'>
print s.decode('raw-unicode-escape').encode('utf-8')
Привет world!
我需要的就是把str格式的 \u041f... 转换成unicode格式。
f = open("chrome.json", "r")
data = f.readlines()
f.close()
urls = [] # for links
names = [] # for link titles
ind = 0
for i in data:
if i.find('"url":') != -1:
urls.append(i.split('"')[3])
names.append(data[ind-2].split('"')[3])
ind += 1
fw = open("chrome.html","w")
fw.write("<html><body>\n")
for n in names:
fw.write(n.decode('raw-unicode-escape').encode('utf-8') + '<br>')
fw.write("</body></html>")
4 个回答
你可以在文件开头加上utf-8的BOM,这样Chrome就知道要把它当作utf-8格式来读取,而不是ascii格式:
fw = codecs.open("chrome.html","w","utf-8")
fw.write(codecs.BOM_UTF8.decode('utf-8'))
fw.write(u'你好')
哦,不过如果你在Python中打开这个文件,记得要用 'utf-8-sig'
来去掉BOM。
也许你需要把unicode编码成utf-8,但我觉得codecs库已经帮你做了这个,对吧:
这是一个JSON文件,所以你应该用JSON解析器来读取它。这样你就能直接得到一个Unicode字符串,而不需要自己去处理那些转义字符。这种方法更可靠,也更简单,因为JSON字符串和Python字符串的格式其实是不一样的。
虽然它们看起来很相似,都是用\u
格式,但你现在的代码在处理其他转义字符时会出问题,更别提它还依赖于JSON文件中属性的顺序和空格设置,这让它变得非常脆弱。
import json, cgi, codecs
with open('chrome.json') as fp:
bookmarks= json.load(fp)
with codecs.open('chrome.html', 'w', 'utf-8') as fp:
fp.write(u'<html><body>\n')
for root in bookmarks[u'roots'].values():
for child in root['children']:
fp.write(u'<a href="%s">%s</a>' % (
cgi.escape(child[u'url']),
cgi.escape(child[u'name'])
))
fp.write(u'</body></html>')
另外,要注意使用cgi.escape
来对字符串中的<
或&
字符进行HTML编码。
顺便说一下,不仅仅是俄语,页面名称中出现非ASCII字符的情况也很常见。举个例子:
name=u'Python Programming Language \u2013 Official Website'
url=u'http://www.python.org/'
作为一种替代方案,避免使用那种脆弱的代码,比如
urls.append(i.split('"')[3])
names.append(data[ind-2].split('"')[3])
# (1) relies on name being 2 lines before url
# (2) fails if there is a `"` in the name
# example: "name": "The \"Fubar\" website",
你可以使用json模块来处理输入文件。如果你用的是Python 2.5,可以去simplejson下载。
这里有一个模拟你代码的脚本:
try:
import json
except ImportError:
import simplejson as json
import sys
def convert_file(infname, outfname):
def explore(folder_name, folder_info):
for child_dict in folder_info['children']:
ctype = child_dict.get('type')
name = child_dict.get('name')
if ctype == 'url':
url = child_dict.get('url')
# print "name=%r url=%r" % (name, url)
fw.write(name.encode('utf-8') + '<br>\n')
elif ctype == 'folder':
explore(name, child_dict)
else:
print "*** Unexpected ctype=%r ***" % ctype
f = open(infname, 'rb')
bmarks = json.load(f)
f.close()
fw = open(outfname, 'w')
fw.write("<html><body>\n")
for folder_name, folder_info in bmarks['roots'].iteritems():
explore(folder_name, folder_info)
fw.write("</body></html>")
fw.close()
if __name__ == "__main__":
convert_file(sys.argv[1], sys.argv[2])
在Windows 7专业版上使用Python 2.5.4进行了测试。