отображение юникода Python в HTML - PullRequest
5 голосов
/ 26 февраля 2011

Я пишу скрипт для экспорта моих ссылок и их заголовков из chrome в html.
Закладки Chrome хранятся в формате json, в кодировке utf
Некоторые заголовки на русском языке, поэтому они хранятся так:
"имя ":" \ u0425 \ 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 ... в Юникод .

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 ]

1 голос
/ 27 февраля 2011

Это файл JSON, поэтому читайте его с помощью анализатора JSON.Это даст вам строку Unicode напрямую, без необходимости ее удаления.Это будет намного надежнее (а также проще), поскольку строки JSON не имеют тот же формат, что и строки Python.

(Они довольно похожи, и обе используют *Формата 1005 *, но ваш текущий код будет плохо обрабатываться для других экранированных символов, не говоря уже о том, что он зависит от точного порядка атрибутов и настроек пробелов в файле 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-кодирования любых < или & символов в строках.

1 голос
/ 27 февраля 2011

Кстати, это не просто русский язык; не-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])

Протестировано с использованием Python 2.5.4 в Windows 7 Pro.

0 голосов
/ 26 февраля 2011

Вы можете включить спецификацию utf-8, так что chrome знает, что читать ее как utf-8, а не как ascii:

fw = codecs.open("chrome.html","w","utf-8")
fw.write(codecs.BOM_UTF8.decode('utf-8'))
fw.write(u'你好')

Да, но если вы открываете fw в python, не забудьте использовать 'utf-8-sig' чтобы раздеть спецификацию.

Может быть, вам нужно кодировать юникод в utf-8, но я думаю, что кодеки уже это делают, верно:

0 голосов
/ 26 февраля 2011

Я не уверен, где вы пытаетесь отобразить русский текст, но в интерпретаторе вы можете сделать следующее, чтобы увидеть русский текст:

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

Это даст следующий вывод:

Х а б

Если вы храните его в формате html, лучше оставить его как '\u0425...', пока вам не понадобится преобразовать его.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...