默认情况下,lxml不会低位和wbr标记,用于在长字中添加分词符。如果格式为<wbr></wbr>
,则格式为<wbr>
,类似于br标记。
如何将此行为添加到lxml?
答案 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/tmp
(diff -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)
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'