デフォルトでは、lxmlはwbrタグを理解していません。これは、長い単語に単語区切りを追加するために使用されます。brタグと同様に、<wbr></wbr>
単純にとしてフォーマットする必要がある場合と同じようにフォーマットします。<wbr>
この動作をlxmlに追加するにはどうすればよいですか?
実際、libxml2にパッチを適用することは難しくありません(このウォークスルーは、Python2.7.3を使用するUbuntu11.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
pythonlibxml2バインディングをインストールしてインストールします。
sudo make install
cd to_python_bindings
sudo python setup.py install
wbr_test.py
もう一度テストして、最新のlibxml2バージョンで失敗することを確認します。
まず、eginのコピーを作成HTMLparser.c
します/var/tmp
。
次に、libxml2ソースのトップレベルにあるファイルHTMLparser.cを編集します。単語を検索しますforced
(1回だけ)。<br>
タグの定義が表示されます。見つけた行から始まる3行をコピーします。最も適切な挿入点は、終了の直前(の定義の後<var>
)です。'}'
表の最後のコンマを正しく取得するには、。が付いている行ではなく、が付いている行の前に3行を挿入し'};'
ます。
新しく挿入されたコードで、置換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
朗報です!これは完全に不可能です。HTMLタグ名はに直接焼き付けられ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に対していくつかのバグを報告するかもしれないと思います。
<wbr>
HTML5にしか存在しないので、正しいことは使用することだと思いますlxml.html.html5parser
。
それを除けば、空のタグのリストは通常のPythonコードで定義されているため、いつでもモンキーパッチを適用できます。lxml.html.defs.empty_tagsを参照してください。パッチは大歓迎です、きっと。:)
簡単な解決策として、replace
文字列のメソッドを使用して終了タグを削除してみませんか?
>>> t = 'Thisisa<wbr></wbr>test'
>>> t.replace('</wbr>', '')
'Thisisa<wbr>test'