Python在HTML中显示Unicode

5

我正在编写脚本,将我的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!

我需要将\u041f...的str转换为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>")

对于Python 3,请使用:s.encode('utf-8').decode('raw-unicode-escape') - Demiurg
4个回答

1
顺便说一下,这不仅仅是俄语的问题;非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 Pro 上使用 Python 2.5.4 进行测试。


1

这是一个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 编码以转义任何 <& 字符。

0

我不确定您想在哪里显示俄语文本,但是在解释器中,您可以执行以下操作以查看俄语文本:

s = '\u0425\u0430\u0431'
l = s.split('\u')
l.remove('')
for x in l:
    print(unichr(int(x, 16))),

这将会输出以下内容:
Х а б

如果你要将它存储在HTML中,最好保留为'\u0425...',直到需要进行转换。

希望这能帮到你。


0
你可以包含 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中打开fw,请记得使用'utf-8-sig'来去除BOM。

也许你需要将Unicode编码为UTF-8,但我认为codecs已经做到了,对吧:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接