lxml удаляет пробелы и разрывы строк в <head> - PullRequest
6 голосов
/ 24 июня 2011

Эта маленькая программа:

from lxml.html import tostring, fromstring
e = fromstring('''
<html><head>
        <link href="/comments.css" rel="stylesheet" type="text/css">
        <link href="/index.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <span></span>
        <span></span>
    </body>
</html>''')

print (tostring(e, encoding=str)) #unicode on python 2

напечатает:

<html><head><link href="/comments.css" rel="stylesheet" type="text/css"><link
href="/index.css" rel="stylesheet" type="text/css"></head><body>
        <span></span>
        <span></span>
    </body></html>

Пробелы и разрывы строк в удаленных головках.Это происходит, даже если мы поместим два элемента в .Кажется, что пустые текстовые узлы (\ s *) между элементами заголовка удалены.

Как я могу сохранить пробелы и разрывы строк между s?(Я ожидаю, что вывод будет точно таким же, как ввод)

Ответы [ 2 ]

2 голосов
/ 24 июня 2011

для меня

print (tostring(e, encoding=str))

возвращает

>>> print (tostring(e, encoding=str))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/lxml/html/__init__.py", line 1493, in tostring
    encoding=encoding)
  File "lxml.etree.pyx", line 2836, in lxml.etree.tostring (src/lxml/lxml.etree.c:53416)
TypeError: descriptor 'upper' of 'str' object needs an argument

Я не могу говорить с descrepencey, но я предлагаю установить аргумент pretty_print в true

>>> etree.tostring(e, pretty_print=True)
'<html>\n  <head>\n    <link href="/comments.css" rel="stylesheet" type="text/css"/>\n    <link href="/index.css" rel="stylesheet" type="text/css"/>\n  </head>\n  <body>\n        <span/>\n        <span/>\n    </body>\n</html>\n'

вам нужно будет импортировать этри from lxml import etree

при выводе в выходной файл пробелы и переводы строк будут сохранены. Также с print

>>> print(etree.tostring(e, pretty_print=True))
<html>
  <head>
    <link href="/comments.css" rel="stylesheet" type="text/css"/>
    <link href="/index.css" rel="stylesheet" type="text/css"/>
  </head>
  <body>
        <span/>
        <span/>
    </body>
</html>

Я уверен, что вы проверили API , но если у вас нет информации о tostring () . Также можно предположить, что вы видели учебник на веб-сайте lxml. Я хотел бы увидеть больше «хороших» ресурсов. Я новичок в lxml сам и все новое и хорошо для чтения будет приветствоваться.

Обновлено

вы сказали, что вы рассмотрите sed, если не сможете найти хорошее решение для Python.

это должно быть выполнено с sed

sed -i '1,2d;' input.html; sed -i '1 i\<html><head>' input.html

это выполняется две sed процедуры. первая удаляет первые 2 строки. вторая вставка <html><head> в первой строке.

ОБНОВЛЕНИЕ № 2

Я должен был подумать об этом больше. Вы можете сделать это с Python

    >>> import re
    >>> newString = re.sub('\n  ', '', etree.tostring(e,encoding=unicode,pretty_print=True), count=1)
    >>> print(newString)
      <html><head>
            <link href="/comments.css" rel="stylesheet" type="text/css"/>
            <link href="/index.css" rel="stylesheet" type="text/css"/>
         </head>
         <body>
           <span/>
           <span/>
        </body>
   </html>
1 голос
/ 27 июля 2011

Наконец, я использовал html5lib для анализа html и создания с его помощью lxml-подобного дерева.

parser = html5lib.HTMLParser(tree=html5lib.getTreeBuilder("lxml"), namespaceHTMLElements=False)

...