lxml删除空格和换行符

时间:2011-06-24 14:37:07

标签: python python-3.x html-parsing lxml

这个小程序:

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>

移除了头部的空格和换行符。 即使我们放置两个&lt; link&gt;也会发生这种情况。 &lt; body&gt;中的元素。 似乎删除了头元素之间的空白文本节点(\ s *)。

如何在&lt; link&gt;之间保留空格和换行符? (我希望输出与输入完全相同)

2 个答案:

答案 0 :(得分:2)

对我来说

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

我不能说出贬义,但我建议将论据pretty_print设为真

>>> 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'

您需要导入etree from lxml import etree

当输出到outfile时,空格和换行符将被保存。还有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网站上看到tutorial也是安全的。我希望看到一些更“好”的资源。我自己是lxml的新手,我会欢迎任何新的和阅读。

已更新

你说如果你找不到一个好的python解决方案,你会考虑sed

这应该通过sed

来实现

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

这是运行两个sed程序。第一行删除前两行。第二行在第一行插入<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 :(得分:1)

最后,我使用html5lib解析html并使用它生成像树一样的lxml。

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