How to add outer tag to BeautifulSoup object
<p>I am trying to replace the content of an iframe a BeautifulSoup object. Let say this</p>

<pre><code> s="""
 &lt;!DOCTYPE html&gt;
 &lt;html&gt;
 &lt;body&gt;

 &lt;iframe src="http://www.w3schools.com"&gt;         
   &lt;p&gt;Your browser does not support iframes.&lt;/p&gt;
 &lt;/iframe&gt;

 &lt;/body&gt;
 &lt;/html&gt;
 """
</code></pre>

<p>is the original html being parsed with</p>

<pre><code>dom = BeatifulSoup(s, 'html.parser')
</code></pre>

<p>and I get the iframe with <code>f = dom.find('iframe')</code></p>

<p>Now I want to replace only the content of the iframe with another BeautifulSoup object, eg the object newBO. If I do <code>f.replace_with(newBO)</code>
it works but I lose the hierarchy of the original file because the iframe tag is gone. If instead of a BeautifulSoup object I had just a string I could do <code>f.string = 'just a string'</code> and that would replace the content, but if I do <code>f.string = newBO</code></p>

<p>I get</p>

<blockquote>
  <p>TypeError: 'NoneType' object is not callable</p>
</blockquote>

<p>So I am trying to use the <code>replace_with</code> but add an <code>iframe</code> tag to the newBO. How can I do that? Can you suggest some other way?</p>

<p><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#extract" rel="nofollow"><em>extract</em></a> the content then <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#insert" rel="nofollow">insert</a>:</p>

<pre><code>from bs4 import BeautifulSoup
dom = BeautifulSoup(s, 'html.parser')

f = dom.find('iframe')
for ele in f.find_all():
    ele.extract()
new = BeautifulSoup("&lt;div&gt;foo&lt;/div&gt;").find("div")
f.insert(0, new)
print(dom)
</code></pre>

<p>Which would give you:</p>

<pre><code> &lt;!DOCTYPE html&gt;

&lt;html&gt;
&lt;body&gt;
&lt;iframe src="http://www.w3schools.com"&gt;&lt;div&gt;foo&lt;/div&gt;

&lt;/iframe&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>To also remove any string set <code>f.string=""</code>:</p>

<pre><code>f = dom.find('iframe')

for ele in f.find_all():
    print(type(ele))
    ele.extract()
f.string = ""
new = BeautifulSoup("&lt;div&gt;foo&lt;/div&gt;","html.parser").find("div")
f.insert(0, new)
print(dom)
</code></pre>

<p>Which would then give you:</p>

<pre><code>&lt;!DOCTYPE html&gt;

&lt;html&gt;
&lt;body&gt;
&lt;iframe src="http://www.w3schools.com"&gt;&lt;div&gt;foo&lt;/div&gt;&lt;/iframe&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>In this case you could also use <code>f.append(new)</code> as it is going to be the only element.</p>

python html iframe beautifulsoup