5

デフォルトでは、lxmlはwbrタグを理解していません。これは、長い単語に単語区切りを追加するために使用されます。brタグと同様に、<wbr></wbr>単純にとしてフォーマットする必要がある場合と同じようにフォーマットします。<wbr>

この動作をlxmlに追加するにはどうすればよいですか?

4

4 に答える 4

10

実際、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行を挿入し'};'ます。

新しく挿入されたコードで、置換brwbrてに変更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

于 2012-05-28T07:04:59.170 に答える
5

朗報です!これは完全に不可能です。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に対していくつかのバグを報告するかもしれないと思います。

于 2012-05-23T22:04:30.587 に答える
3

<wbr>HTML5にしか存在しないので、正しいことは使用することだと思いますlxml.html.html5parser

それを除けば、空のタグのリストは通常​​のPythonコードで定義されているため、いつでもモンキーパッチを適用できます。lxml.html.defs.empty_tagsを参照してください。パッチは大歓迎です、きっと。:)

于 2012-04-26T22:19:43.827 に答える
1

簡単な解決策として、replace文字列のメソッドを使用して終了タグを削除してみませんか?

>>> t = 'Thisisa<wbr></wbr>test'
>>> t.replace('</wbr>', '')
'Thisisa<wbr>test'
于 2012-05-29T19:57:23.310 に答える