Как сохранить информацию пространства имен при разборе HTML с помощью lxml? - PullRequest
8 голосов
/ 06 июля 2011
>>> from lxml.etree import HTML, tostring
>>> tostring(HTML('<fb:like>'))
'<html><body><like/></body></html>'

Обратите внимание, как тег меняется с <fb:like> на <like>.

Это значительно усложняет обработку страниц с XFBML и lxml. (То же самое происходит с <g:plusone></g:plusone>)

Любая помощь приветствуется.

Ответы [ 2 ]

1 голос
/ 14 апреля 2015

Одним из способов решения этой проблемы является исправление libxml2 .

Ссылаясь на исходный код libxml2.9.2 (https: //git.gnome.org/browse/libxml2/tree/?id=v2.9.2), в SAX2.c (https: //git.gnome. org / browse / libxml2 / tree / SAX2.c? id = v2.9.2) (внутренний синтаксический анализатор SAX, использованный для создания дерева DOM) в строке 1699 атрибуты с xmlns не анализируются в режиме HTML и анализируются как любые другие атрибуты в строке и 1740. Следовательно, имеет смысл настроить строку 1622, которая разбивает имя на префикс и локальную часть. Изменения:

name = xmlSplitQName(ctxt, fullname, &prefix);

в

if (!ctxt->html) {
    name = xmlSplitQName(ctxt, fullname, &prefix);
} else {
    name = xmlStrdup(fullname);
    prefix = NULL;
}

Тогда libxml2 будет считать теги, такие как <o:p>, для элементов с именем o:p, то есть двоеточие включено в имя элемента без особого значения. Это правильная интерпретация в HTML. Например, спецификация HTML5 гласит :

В синтаксисе HTML префиксы пространств имен и объявления пространств имен не имеют того же эффекта, что и в XML. Например, двоеточие не имеет специального значения в именах элементов HTML.

Надеюсь, это изменение будет одобрено для будущей версии libxml2. Есть открытый отчет об ошибке (https: //bugzilla.gnome.org/show_bug.cgi?id=654146).

1 голос
/ 06 июля 2011

Попробуйте добавить отсутствующие определения префикса пространства имен.lxml исключит пространства имен, в противном случае , предположительно, чтобы вам было легче.

Скорее всего, сайты, которые вы пытаетесь проанализировать, не будут содержать этих определений пространства имен, поэтому вы должны добавить их.

Примерно так: xmlns: adlcp = "http://xxx/yy/zzz"

...