Приведенный ниже код может выполнить то, о чем вы просите, при условии, что дочерний и родительский теги имеют разные имена и не являются только прописными и строчными версиями друг друга
html = """
<B ID=101>
<a id=”A1”>Today is a nice day.
<a id=”A2”>Today is a very nice day.
<a id=”A3”>Today is a very very nice day.
</B>
<B ID=102>
<a id=”A1”>Today is a nice day2.
<a id=”A2”>Today is a very nice day2.
<a id=”A3”>Today is a very very nice day2.
</B>
"""
invalid_tags = ['a',"html","body"]
soup = BeautifulSoup(html,"lxml")
for tag in invalid_tags:
for match in soup.findAll(tag):
match.replaceWithChildren()
print (soup)
Это потому, что BeautifulSoup по умолчанию имеет делос HTML-данными. HTML не чувствителен к регистру;при разборе все теги в нижнем регистре.
Если вам нужно сопоставить теги с учетом регистра, вам нужно проанализировать документ как XML. Установите lxml (по pip) и скажите BeautifulSoup использовать этот анализатор в режиме XML, например:
soup = BeautifulSoup(source, 'xml')