BeautifulSoup: просто входите в тег, независимо от того, сколько охватывающих тегов есть
Я пытаюсь очистить весь внутренний html от элементов <p>
на веб-странице с помощью BeautifulSoup. Есть внутренние теги, но мне все равно, я просто хочу получить внутренний текст.
Например, для:
<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>
Как я могу извлечь:
Red
Blue
Yellow
Light green
Ни .string
, ни .contents[0]
делает то, что мне нужно. Также не .extract()
, потому что я не хочу указывать внутренние теги заранее - я хочу иметь дело с тем, что может произойти.
Есть ли способ "просто получить видимый HTML" в BeautifulSoup?
---- UPDATE ------
По совету, пытаясь:
soup = BeautifulSoup(open("test.html"))
p_tags = soup.findAll('p',text=True)
for i, p_tag in enumerate(p_tags):
print str(i) + p_tag
Но это не помогает - он печатает:
0Red
1
2Blue
3
4Yellow
5
6Light
7green
8
Ответы
Ответ 1
Короткий ответ: soup.findAll(text=True)
Об этом уже был дан ответ fooobar.com/questions/66599/... и в документация BeautifulSoup.
UPDATE:
Чтобы уточнить, рабочая часть кода:
>>> txt = """\
<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>
"""
>>> import BeautifulSoup
>>> BeautifulSoup.__version__
'3.0.7a'
>>> soup = BeautifulSoup.BeautifulSoup(txt)
>>> for node in soup.findAll('p'):
print ''.join(node.findAll(text=True))
Red
Blue
Yellow
Light green
Ответ 2
Принятый ответ велик, но ему сейчас 6 лет, поэтому здесь Beautiful Soup 4 version этого ответа:
>>> txt = """\
<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>
"""
>>> from bs4 import BeautifulSoup, __version__
>>> __version__
'4.5.1'
>>> soup = BeautifulSoup(txt, "html.parser")
>>> print("".join(soup.strings))
Red
Blue
Yellow
Light green
Ответ 3
Сначала преобразуем html в строку с помощью str
. Затем используйте следующий код с вашей программой:
import re
x = str(soup.find_all('p'))
content = str(re.sub("<.*?>", "", x))
Это называется regex
. Это приведет к удалению всего, что происходит между двумя тегами html (включая теги).