2011-01-05 11 views
5

Mi pregunta está ligeramente relacionado con: Strip HTML from strings in PythonPython: html tira de datos de texto

Busco una forma sencilla de banda de código HTML de texto. Por ejemplo:

string = 'foo <SOME_VALID_HTML_TAG> something </SOME_VALID_HTML_TAG> bar' 
stripIt(string) 

Otorgaría foo bar.

¿Hay alguna herramienta simple para lograr esto en Python? El código HTML podría estar anidado.

+0

es "SOME_VALID_HTML_TAG" establecido en una etiqueta en particular? ¿Quieres que se elimine la etiqueta más externa? – milkypostman

+0

Creo que es posible que desee utilizar la respuesta aceptada sobre la pregunta que ha vinculado, ¿qué diferencia hay entre lo que está haciendo? – girasquid

+0

En la pregunta relacionada, el usuario quería stripIt (' foo') para ceder foo, mientras que en mi caso quiero que vuelva ''. – Jernej

Respuesta

5
from BeautifulSoup import BeautifulSoup 

def removeTags(html, *tags): 
    soup = BeautifulSoup(html) 
    for tag in tags: 
     for tag in soup.findAll(tag): 
      tag.replaceWith("") 

    return soup 


testhtml = ''' 
<html> 
    <head> 
     <title>Page title</title> 
    </head> 
    <body>text here<p id="firstpara" align="center">This is paragraph <b>one</b>.</p> 
     <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p> 
    </body> 
</html>''' 

print removeTags(testhtml, 'b', 'p') 
2

Pruebe esta solución:

from BeautifulSoup import BeautifulSoup 

def stripIt(string, tag): 
    soup = BeautifulSoup(string) 

    rmtags = soup.findAll(tag) 
    for t in rmtags: 
     string = string.replace(str(t), '') 
    return string 

string = 'foo <p> something </p> bar' 
print stripIt(string, 'p') 
>>> foo bar 

string = 'foo <a>bar</a> baz <a>quux</a>' 
print stripIt(string, 'a') 
>>> foo baz 

Editar: Esto sólo funciona en válidamente anidados etiquetas, así por ejemplo:

string = 'blaz <div>baz <div>quux</div></div>' 
print stripIt(string, 'div') 
>>> blaz 

string = 'blaz <a>baz <a>quux</a></a>' 
print stripIt(string, 'a') 
>>> blaz <a>baz </a> 
0

usted puede tomar ventaja de HTMLParser reemplazando métodos en consecuencia:

from HTMLParser import HTMLParser 

class HTMLStripper(HTMLParser): 

    text_parts = [] 
    depth = 0 

    def handle_data(self, data): 
     if self.depth == 0: 
      self.text_parts.append(data.strip()) 

    def handle_charref(self, ref): 
     data = unichr(int(ref)) 
     self.handle_data(data) 

    def handle_starttag(self, tag, attrs): 
     self.depth += 1 

    def handle_endtag(self, tag): 
     if self.depth > 0: 
      self.depth -= 1 

    def handle_entityref(self, ref): 
     try: 
      data = unichr(name2codepoint[ref]) 
      self.handle_data(data) 
     except KeyError: 
      pass 

    def get_stripped_text(self): 
     return ' '.join(self.text_parts) 

def strip_html_from_text(html): 
    parser = HTMLStripper() 
    parser.feed(html) 
    return parser.get_stripped_text() 

def main(): 
    import sys 
    html = sys.stdin.read() 
    text = strip_html_from_text(html) 
    print text 

if __name__ == '__main__': 
    main() 
6
import lxml.html 
import re 

def stripIt(s): 
    doc = lxml.html.fromstring(s) # parse html string 
    txt = doc.xpath('text()')  # ['foo ', ' bar'] 
    txt = ' '.join(txt)    # 'foo bar' 
    return re.sub('\s+', ' ', txt) # 'foo bar' 

s = 'foo <SOME_VALID_HTML_TAG> something </SOME_VALID_HTML_TAG> bar' 
stripIt(s) 

vuelve

foo bar 
+0

Creo que, lxml es mejor que otros módulos, esto funciona como encanto. –

+0

Esto es bueno porque solo hay un espacio entre el 'foo' y la 'barra' resultante, como solicitó OP. Algunas de las otras soluciones dejan dos espacios. – mmmdreg

2

Si alguien tiene este problema y ya está trabajando con el lenguaje de plantillas de jinja: Puede utilizar el filtro striptags en las plantillas y la función jinja2.filters.do_striptags() en el código.

3

Usted podría utilizar expresiones regulares:

def stripIt(s): 
    txt = re.sub('<[^<]+?>.*?</[^<]+?>', '', s) # Remove html tags 
    return re.sub('\s+', ' ', txt)    # Normalize whitespace 

Sin embargo, preferiría solución de Hugh Bothwell, ya que sería más robusta que la expresión regular puro.

Cuestiones relacionadas