python - how - BeautifulSoup: solo ingresa dentro de una etiqueta, no importa cuántas etiquetas envolventes haya
python beautifulsoup find element (4)
Estoy tratando de eliminar todos los html internos de los elementos <p>
en una página web usando BeautifulSoup. Hay etiquetas internas, pero no me importa, solo quiero obtener el texto interno.
Por ejemplo, para:
<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>
Cómo puedo extraer:
Red
Blue
Yellow
Light green
Ni .string
ni .contents[0]
hacen lo que necesito. Tampoco lo hace .extract()
, porque no quiero tener que especificar las etiquetas internas de antemano. Quiero tratar con cualquier cosa que pueda ocurrir.
¿Hay un método de "solo obtener el HTML visible" en BeautifulSoup?
----ACTUALIZAR------
En consejos, tratando:
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
Pero eso no ayuda, imprime:
0Red
1
2Blue
3
4Yellow
5
6Light
7green
8
La respuesta aceptada es excelente, pero ahora tiene 6 años, así que aquí está la versión actual de Beautiful Soup 4 de esta respuesta:
>>> 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
Normalmente, los datos eliminados del sitio web contendrán etiquetas. Para evitar esas etiquetas y mostrar solo contenido de texto, puede usar el atributo de texto.
Por ejemplo,
from BeautifulSoup import BeautifulSoup
import urllib2
url = urllib2.urlopen("https://www.python.org")
content = url.read()
soup = BeautifulSoup(content)
title = soup.findAll("title")
paragraphs = soup.findAll("p")
print paragraphs[1] //Second paragraph with tags
print paragraphs[1].text //Second paragraph without tags
En este ejemplo, recopilo todos los párrafos del sitio de Python y lo visualizo con etiquetas y sin etiquetas.
Primero, convierta el html a una cadena usando str
. Luego, use el siguiente código con su programa:
import re
x = str(soup.find_all(''p''))
content = str(re.sub("<.*?>", "", x))
Esto se llama regex
. Este eliminará todo lo que se encuentre entre dos etiquetas html (incluidas las etiquetas).
Respuesta corta: soup.findAll(text=True)
Esto ya ha sido respondido, aquí en y en la documentación de BeautifulSoup .
ACTUALIZAR:
Para aclarar, una pieza de código de trabajo:
>>> 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