2011-08-11 20 views
12

私はlxml.htmlライブラリを使ってHTML文書を解析しています。Python: `lxml.html`を使ってタグにHTMLコンテンツを挿入

私はcontent_tag呼び出すことを、特定のタグを設置し、私はその内容(<div></div>の間、すなわち、テキストなど)を変更したいと新しいコンテンツがその中にいくつかのHTMLを文字列である、それは'Hello <b>world!</b>'だと言います。

どうすればよいですか?私はcontent_tag.text = 'Hello <b>world!</b>'を試みたが、それはは任意のHTMLをエスケープせずなど&lt;

私はテキストを注入したいと<を交換し、すべてのHTMLタグをエスケープします。どうやってやるの?

#!/usr/bin/env python2.6 
from lxml.html import fromstring, tostring 
from lxml.html import builder as E 
fragment = """\ 
<div id="outer"> 
    <div id="inner">This is div.</div> 
</div>""" 

div = fromstring(fragment) 
print tostring(div) 
# <div id="outer"> 
# <div id="inner">This is div.</div> 
# </div> 
div.replace(div.get_element_by_id('inner'), E.DIV('Hello ', E.B('world!'))) 
print tostring(div) 
# <div id="outer"> 
# <div>Hello <b>world!</b></div></div> 

も参照してください:

+0

_nice_方法は、 'world'のための新しい子ノードを追加することです。 – katrielalex

+0

どうすればいいですか? –

答えて

8

これは一つの方法ですhttp://lxml.de/lxmlhtml.html#creating-html-with-the-e-factory

編集:だから、私は以前、私はすべてのlxmlのとその慣れていないだと告白している必要があります。私はドキュメントとソースを簡単に見ていましたが、クリーンなソリューションは見つかりませんでした。たぶん、もっと慣れ親しんだ人が立ち寄り、私たちを両方とも真っ直ぐにしてくれるでしょう一方

、これが動作するようだが、十分にテストされていません。

import lxml.html 
content_tag = lxml.html.fromstring('<div>Goodbye.</div>') 
content_tag.text = '' # assumes only text to start 
for elem in lxml.html.fragments_fromstring('Hello <b>world!</b>'): 
    if type(elem) == str: #but, only the first? 
     content_tag.text += elem 
    else: 
     content_tag.append(elem) 
print lxml.html.tostring(content_tag) 

編集再び:と、このバージョンはcontent_tagがないと仮定すると、テキストや子供

somehtml = 'Hello <b>world!</b>' 
# purge element contents 
content_tag.text = '' 
for child in content_tag.getchildren(): 
    content_tag.remove(child) 

fragments = lxml.html.fragments_fromstring(somehtml) 
if type(fragments[0]) == str: 
    content_tag.text = fragments.pop(0) 
content_tag.extend(fragments) 
+0

その方法は2つの理由から私にとってはうまくいかない:(1)タグを置き換えたくない、タグの内容を置き換えたい、(2)挿入したいhtmlセグメントが既に入っているテキスト形式では、私は 'E 'でそれを構築したくありません。 –

+0

@Ram Rachum:更新された回答、役立つことを願っています。 – Marty

0

を削除しますサブ要素がある場合は、次のようにしてください。

from lxml import html 
from lxml.html.builder import B 

... 

content_tag.text = 'Hello ' 
content_tag.append(B('world!')) 
print html.tostring(content_tag) 
+0

私のHTMLテキストはあらかじめわかっていないので、コード内にHTML構造として構築することはできません。 –

+0

ああ、あなたの質問にそのことを明記していない(「あらかじめわかっていない」部分)。 – sayap

+0

mwalshさんの編集された回答がうまく見え、任意のhtmlでうまくいくはずです。 – sayap

0

の周りいじりの後、私はこの解決策を見つけた:あなたが本当にDOM構造を変更しようとしているので、

fragments = lxml.html.fragments_fromstring(<string with tags to inject>) 
last = None 

for frag in fragments: 
    if isinstance(frag, lxml.etree._Element): 
    content_tag.append(frag) 
    last = frag 
    else: 
    if last: 
     last.tail = frag 
    else: 
     content_tag.text = frag 
関連する問題