Уведомления

Группа в Telegram: @pythonsu

#1 Май 18, 2017 16:50:05

Stright
От: Кострома
Зарегистрирован: 2015-01-20
Сообщения: 139
Репутация: +  16  -
Профиль   Отправить e-mail  

Вопрос по lxml

Здравствуйте! Библиотека lxml по-умолчанию экранирует теги, если они встречаются в атрибуте text элемента.

 from lxml import etree
tree = etree.HTML('<div></div>')
div = tree.xpath('//div')[0]
div.text = '<p></p>'
print(etree.tostring(tree, pretty_print=True).decode())

 <html>
  <body>
    <div>&lt;p&gt;&lt;/p&gt;</div>
  </body>
</html>

Можно ли изменить поведение lxml, чтобы результат был такой:
 <html>
  <body>
    <div><p></p></div>
  </body>
</html>
?

Отредактировано Stright (Май 18, 2017 16:52:26)

Офлайн

#2 Май 19, 2017 00:07:53

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Вопрос по lxml

С html-документом надо работать через lxml.html, потому что html хоть и похож на xml, но не является его подмножеством (нельзя считать, что html - это такой суженный xml).

  
>>> from lxml import html
>>> 
>>> doc = html.document_fromstring('<div></div>')
>>> 
>>> div = doc.xpath('//div')[0]
>>> div.append(html.Element('p'))
>>> 
>>> print(html.tostring(doc, pretty_print=True, encoding='unicode'))
<html><body><div><p></p></div></body></html>
>>>



Отредактировано py.user.next (Май 19, 2017 00:14:53)

Офлайн

#3 Май 19, 2017 00:14:09

Stright
От: Кострома
Зарегистрирован: 2015-01-20
Сообщения: 139
Репутация: +  16  -
Профиль   Отправить e-mail  

Вопрос по lxml

Да, просто тег добавить можно, как дочерний элемент, а если мне надо добавить не тег, а шаблон, что-то вроде:

 '{% if name %}<p>{{name}}</p>{% endif %}'
и на выходе получить:
 <html>
  <body>
    <div>{% if name %}<p>{{name}}</p>{% endif %}</div>
  </body>
</html>
?

Отредактировано Stright (Май 19, 2017 00:15:41)

Офлайн

#4 Май 19, 2017 00:21:14

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Вопрос по lxml

  
>>> from lxml import html
>>> 
>>> doc = html.document_fromstring('<div></div>')
>>> 
>>> div = doc.xpath('//div')[0]
>>> div.append(html.Element('p'))
>>> div[0].text = '{pattern1}'
>>> 
>>> pat = html.tostring(doc, pretty_print=True, encoding='unicode')
>>> out = pat.format(pattern1='<x>')
>>> out
'<html><body><div><p><x></p></div></body></html>\n'
>>>

Тут вот видно, что не проработаны аргументы у tostring()
http://lxml.de/api/lxml.html-module.html#tostring
Аргумент pretty_print указан, а описания его нет. А про другой аргумент он пишет, что выводится XML, хотя HTML и XML - это разные языки разметки, поэтому HTML никак нельзя называть XML. Видно, он копипастил документацию и не проработал методы. Так что pretty_print должен работать правильно, но не работает. Это нужно ему написать, чтобы он поправил, тогда код будет выводить всё правильно после обновления модуля lxml. Так что pretty_print оставь там, хоть он и не пашет.



Отредактировано py.user.next (Май 19, 2017 00:34:39)

Офлайн

#5 Май 19, 2017 00:53:26

Stright
От: Кострома
Зарегистрирован: 2015-01-20
Сообщения: 139
Репутация: +  16  -
Профиль   Отправить e-mail  

Вопрос по lxml

А pretty_print вообщем-то и не нужен, результат будет промежуточным и читаться никем не будет. Задача, конечно, сильно упрощена для ясности, но, кажется, это то, что нужно, буду пробовать. Спасибо большое за идею!

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version