lxml和<wbr />标签

时间:2012-04-26 21:52:32

标签: python html lxml wbr

默认情况下,lxml不会低位和wbr标记,用于在长字中添加分词符。如果格式为<wbr></wbr>,则格式为<wbr>,类似于br标记。

如何将此行为添加到lxml?

4 个答案:

答案 0 :(得分:10)

实际上修补libxml2并不困难(本演练是在使用Python 2.7.3的Ubuntu 11.04上完成的)

首先定义测试程序wbr_test.py

from lxml import etree
from cStringIO import StringIO

wbr_html = """\
<html>
  <head>
    <title>wbr test</title>
  </head>
<body>
  Test for a breakable<wbr>word implemenation change
</body>
</html>
"""

parser = etree.HTMLParser()
tree   = etree.parse(StringIO(wbr_html), parser)

result = etree.tostring(tree.getroot(),
                         pretty_print=True, method="html")
if result.split() != wbr_html.split(): # split, as we are not interested in whitespace differences
    print(result)
    print("not ok")
else:
    print("OK")

通过运行python wbr_test.py确保它失败。它应该之前插入<\wbr> <\body>,并在最后打印not ok

下载,摘录和编译libxml2

wget ftp://xmlsoft.org/libxml2/libxml2-2.8.0.tar.gz
tar xvf libxml2-2.8.0.tar.gz 
cd libxml2-2.8.0/
./configure --prefix=/usr
make -j8  # adjust number to match your number of cores

安装并安装python libxml2绑定:

sudo make install
cd to_python_bindings
sudo python setup.py install

再次测试wbr_test.py,确保它使用最新的libxml2版本失败。

首先制作HTMLparser.c的副本,例如在/var/tmp

现在在libxml2源的顶层编辑HTMLparser.c文件。搜索单词forced(仅出现一次)。您将处于<br>标记定义。从刚刚找到的行开始复制三行。最合适的插入点就在结束之前(在<var>的定义之后)。要在表格中输入最后一个逗号,请在仅有'}'的行之前插入三行,而不是'};'的行。

在新插入的代码中将br替换为wbr,并将DECL clear_attrs更改为NULL(假设新标记没有弃用的属性)。

结果应与/var/tmpdiff -u HTMLparser.c /var/tmp)中的版本区别开来,如下所示:

@@ -1039,6 +1039,9 @@
 },
 { "var",   0, 0, 0, 0, 0, 0, 1, "instance of a variable or program argument",
DECL html_inline, NULL, DECL html_attrs, NULL, NULL
+},
+{ "wbr",   0, 2, 2, 1, 0, 0, 1, "possible line break ",
+   EMPTY , NULL , DECL core_attrs, NULL , NULL
 }
 };

制作并安装:

make && sudo make install

再次测试wbr_test.py。应该显示OK

答案 1 :(得分:5)

好消息!这完全不可能。 HTML标记名称为baked right into libxml2

并且lxml.html.html5parser包含一些严重的错误,其修复程序尚未发布。

但是,哎呀,让我们在当地修复它们,看看会发生什么。

>>> lxml.html.tostring(lxml.html.html5parser.fromstring('<p>hello<wbr>world!</p>'), encoding=unicode)
u'<html:p xmlns:html="http://www.w3.org/1999/xhtml">hello<html:wbr></html:wbr>world!</html:p>'

如此接近,但到目前为止。结构是正确的,至少。

再试一次:

>>> lxml.html.tostring(lxml.html.html5parser.fromstring('<p>hello<wbr>world!</p>', parser=lxml.html.html5parser.HTMLParser(namespaceHTMLElements=False)), encoding=unicode)
u'<p>hello<wbr></wbr>world!</p>'

韦尔普。

至少错误

我想我可能会对lxml和libxml2提出一些错误。

答案 2 :(得分:3)

由于<wbr>仅存在于HTML5中,我怀疑正确的事情是使用lxml.html.html5parser

除此之外,空标签列表是在常规Python代码中定义的,因此您可以随时对其进行monkeypatch;见lxml.html.defs.empty_tags。我很确定,欢迎使用补丁。 :)

答案 3 :(得分:1)

作为快速解决方法,为什么不使用replace字符串方法删除关闭标记?

>>> t = 'Thisisa<wbr></wbr>test'
>>> t.replace('</wbr>', '')
'Thisisa<wbr>test'