lxml символы юникода - PullRequest
       6

lxml символы юникода

5 голосов
/ 06 марта 2012

Я новичок в lxml и python.Я пытаюсь разобрать HTML-документ.Когда я выполняю синтаксический анализ с использованием стандартного синтаксического анализатора xml, он будет правильно выводить символы, но я думаю, что он не сможет выполнить синтаксический анализ, поскольку у меня возникли проблемы с поиском по xpath.

Пример файла, который анализируется:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>title</title>
</head>
<body>
    <span id="demo">Garbléd charactérs</span>
</body>
</html>

Код синтаксического анализа:

from lxml import etree

fname = 'output/so-help.html'

# parse
hparser = etree.HTMLParser()
htree   = etree.parse(fname, hparser)

# garbled
htree.write('so-dumpu.html', encoding='utf-8')

# targets
demo_name = htree.xpath("//span[@id='demo']")

# garbled
print 'name: "' + demo_name[0].text

Выход терминала:

name: "Garbléd charactérs

Выход htree.write:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>title</title></head><body>
    <span id="demo">Garbléd charactérs</span>
</body></html>

Ответы [ 3 ]

8 голосов
/ 06 марта 2012

проблема была в том, что вы пытались закодировать уже закодированные данные, вам нужно, чтобы парсер декодировал данные с помощью utf-8.* в исходном коде попробуйте demo_name [0] .text.decode ('utf-8'), и вы увидите

правильный способ сделать это:

from lxml import etree

fname = 'output/so-help.html'

# parse
hparser = etree.HTMLParser(encoding='utf-8')
htree   = etree.parse(fname, hparser)

# garbled
htree.write('so-dumpu.html')

# targets
demo_name = htree.xpath("//span[@id='demo']")

# garbled
print 'name: "' + demo_name[0].text
3 голосов
/ 06 марта 2012

Попробуйте изменить кодировку вывода:

htree.write('so-dumpu.html', encoding='latin1')

и

print 'name: "' + demo_name[0].text.encode('latin1')
2 голосов
/ 06 марта 2012

Я предполагаю, что ваш документ XHTML зашифрован в utf-8. Проблема заключается в том, что кодировка не указана в документе HTML. По умолчанию браузеры и lxml.html предполагают, что HTML-документы кодируются в ISO-8859-1, поэтому ваш документ анализируется неправильно. Если вы откроете его в браузере, он также будет отображаться неправильно.

Вы можете указать кодировку вашего документа следующим образом:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>

Вы можете принудительно применить кодировку, используемую lxml, таким же образом (например, вы можете изменить кодировку, используемую в вашем браузере):

file = open(fname)
filecontents = file.read()
filecontents = filecontents.decode("utf-8")
htree = lxml.html.fromstring(filecontents)
print htree.xpath("//span[@id='demo']")[0].text
...