from mechanize import Browser
br = Browser()
br.open('http://somewebpage')
html = br.response().readlines()
for line in html:
print line
Cuando imprimo una línea en un archivo HTML, intento encontrar una manera de mostrar solo el contenido de cada elemento HTML y no el formato en sí. Si encuentra '<a href="whatever.com">some text</a>'
, solo imprimirá 'algo de texto', '<b>hello</b>'
imprimirá 'hola', etc. ¿Cómo se podría hacer esto?
&
). Puede 1) eliminarlos junto con las etiquetas (a menudo indeseables e innecesarios, ya que son equivalentes a texto sin formato), 2) dejarlos sin cambios (una solución adecuada si el texto eliminado vuelve directamente a un contexto HTML) o 3 ) los decodifica en texto sin formato (si el texto eliminado se va a una base de datos o algún otro contexto que no sea HTML, o si su marco web realiza automáticamente el escape de texto HTML por usted).Respuestas:
Siempre usé esta función para eliminar las etiquetas HTML, ya que solo requiere Python stdlib:
Para Python 3:
Para Python 2:
fuente
&
), así como las etiquetas.__init__
función de la clase principal . Ver aquí: stackoverflow.com/questions/11061058/… .parser = HTMLParser()
yhtml = parser.unescape(html)
al comienzo de la función strip_tags.No he pensado mucho en los casos que se perderán, pero puedes hacer una expresión regular simple:
Para aquellos que no entienden la expresión regular, esto busca una cadena
<...>
, donde el contenido interno está formado por uno o más (+
) caracteres que no es un<
. Esto?
significa que coincidirá con la cadena más pequeña que pueda encontrar. Por ejemplo<p>Hello</p>
, coincidirá<'p>
y por</p>
separado con el?
. Sin ella, coincidirá con toda la cadena<..Hello..>
.Si no
<
aparece etiqueta en html (p. Ej.2 < 3
), Debe escribirse como una secuencia de escape de&...
todos modos, por lo que^<
puede ser innecesario.fuente
&
) sin cambios en la salida.cgi.escape(s, True)
), incluso si "sabe" que no contiene HTML (por ejemplo, porque eliminó el contenido HTML) . Sin embargo, esto no es lo que OP preguntó.Puede usar la
get_text()
función BeautifulSoup .Es recomendable especificar explícitamente el analizador , por ejemplo
BeautifulSoup(html_str, features="html.parser")
, como , para que la salida sea reproducible.fuente
¡Version corta!
Fuente de expresiones regulares: MarkupSafe . Su versión también maneja entidades HTML, mientras que esta rápida no lo hace.
¿Por qué no puedo simplemente quitar las etiquetas y dejarlo?
Una cosa es mantener a las personas alejadas de las
<i>italicizing</i>
cosas, sin dejari
s flotando. Pero otra es tomar aportaciones arbitrarias y hacerlo completamente inofensivo. La mayoría de las técnicas en esta página dejarán intactos elementos como los comentarios no cerrados (<!--
) y los corchetes angulares que no forman parte de las etiquetas (blah <<<><blah
). La versión HTMLParser puede incluso dejar etiquetas completas, si están dentro de un comentario no cerrado.¿Qué pasa si su plantilla es
{{ firstname }} {{ lastname }}
?firstname = '<a'
ylastname = 'href="http://evil.com/">'
todos los separadores de etiquetas de esta página lo dejarán pasar (¡excepto @Medeiros!), porque no son etiquetas completas por sí mismas. Eliminar las etiquetas HTML normales no es suficiente.Django's
strip_tags
, una versión mejorada (ver el siguiente encabezado) de la respuesta principal a esta pregunta, da la siguiente advertencia:¡Sigue sus consejos!
Para eliminar etiquetas con HTMLParser, debe ejecutarlo varias veces.
Es fácil eludir la respuesta principal a esta pregunta.
Mire esta cadena ( fuente y discusión ):
La primera vez que HTMLParser lo ve, no puede decir que
<img...>
es una etiqueta. Parece roto, por lo que HTMLParser no se deshace de él. Solo saca el<!-- comments -->
, dejándote conEste problema fue revelado al proyecto Django en marzo de 2014. Su antiguo
strip_tags
era esencialmente el mismo que la respuesta principal a esta pregunta. Su nueva versión básicamente lo ejecuta en un bucle hasta que ejecutarlo nuevamente no cambia la cadena:Por supuesto, nada de esto es un problema si siempre escapas del resultado de
strip_tags()
.Actualización 19 de marzo de 2015 : hubo un error en las versiones de Django anteriores a 1.4.20, 1.6.11, 1.7.7 y 1.8c1. Estas versiones podrían entrar en un bucle infinito en la función strip_tags (). La versión fija se reproduce arriba. Más detalles aquí .
Cosas buenas para copiar o usar
Mi código de ejemplo no maneja entidades HTML, las versiones empaquetadas de Django y MarkupSafe sí.
Mi código de ejemplo se extrae de la excelente biblioteca MarkupSafe para la prevención de secuencias de comandos entre sitios. Es conveniente y rápido (con aceleraciones en C a su versión nativa de Python). Está incluido en Google App Engine y lo utilizan Jinja2 (2.7 y versiones posteriores) , Mako, Pilones y más. Funciona fácilmente con las plantillas de Django de Django 1.7.
Strip_tags de Django y otras utilidades html de una versión reciente son buenas, pero las encuentro menos convenientes que MarkupSafe. Son bastante independientes, puede copiar lo que necesita de este archivo .
Si necesita quitar casi todas las etiquetas, la biblioteca de Bleach es buena. Puede hacer que aplique reglas como "mis usuarios pueden poner en cursiva las cosas, pero no pueden hacer iframes".
¡Comprenda las propiedades de su etiqueta stripper! Ejecute pruebas de fuzz en él! Aquí está el código que usé para hacer la investigación de esta respuesta.
nota tímida : la pregunta en sí misma se trata de imprimir en la consola, pero este es el principal resultado de Google para "python strip html from string", por lo que esta respuesta es 99% sobre la web.
fuente
Necesitaba una forma de quitar etiquetas y decodificar entidades HTML en texto plano. La siguiente solución se basa en la respuesta de Eloff (que no pude usar porque elimina las entidades).
Una prueba rápida:
Resultado:
Manejo de errores:
&#apos;
válidas (como , que es válido en XML y XHTML, pero no HTML simple) provocarán unValueError
excepción.ValueError
excepción.Nota de seguridad: no confunda la eliminación de HTML (convertir HTML en texto sin formato) con la desinfección de HTML (convertir texto sin formato en HTML). Esta respuesta eliminará HTML y descodificará entidades en texto sin formato, lo que no hace que el resultado sea seguro de usar en un contexto HTML.
Ejemplo:
<script>alert("Hello");</script>
se convertirá a<script>alert("Hello");</script>
, que es un comportamiento 100% correcto, pero obviamente no es suficiente si el texto plano resultante se inserta como está en una página HTML.La regla no es difícil: cada vez que inserte una cadena de texto sin formato en la salida HTML, siempre debe escapar de HTML (usando
cgi.escape(s, True)
), incluso si "sabe" que no contiene HTML (por ejemplo, porque eliminó el contenido HTML) .(Sin embargo, el OP preguntó acerca de imprimir el resultado en la consola, en cuyo caso no se necesita escapar de HTML).
Versión de Python 3.4+: (con doctest!)
Tenga en cuenta que HTMLParser ha mejorado en Python 3 (lo que significa menos código y mejor manejo de errores).
fuente
Hay una manera simple de hacer esto:
La idea se explica aquí: http://youtu.be/2tu9LTDujbw
Puedes verlo trabajando aquí: http://youtu.be/HPkNPcYed9M?t=35s
PD: si está interesado en la clase (sobre depuración inteligente con python), le doy un enlace: http://www.udacity.com/overview/Course/cs259/CourseRev/1 . ¡Es gratis!
¡De nada! :)
fuente
<b class="o'>x</b>
como función de entrada salidasx
. Pero en realidad esta entrada no es válida. Creo que es por eso que las personas prefieren libs.Si necesita preservar entidades HTML (es decir
&
), agregué el método "handle_entityref" a la respuesta de Eloff .fuente
Si desea quitar todas las etiquetas HTML, la forma más fácil que encontré es usar BeautifulSoup:
Probé el código de la respuesta aceptada pero estaba obteniendo "RuntimeError: excedió la profundidad máxima de recursión", lo que no sucedió con el bloque de código anterior.
fuente
''.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
. Aquí la salida es "helloworld", mientras que probablemente quieras que sea "hello world".' '.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
no ayuda ya que se convierte en "he llo world".Aquí hay una solución simple que elimina las etiquetas HTML y decodifica entidades HTML basadas en la
lxml
biblioteca increíblemente rápida :fuente
text_content()
regresa,lxml.etree._ElementUnicodeResult
así que quizás tengas que lanzarlo primero a la cuerdastr
en operaciones de cadena como+
indexación[]
. Se agregó un elenco de buena medida de todos modos.Una solución basada en lxml.html (lxml es una biblioteca nativa y, por lo tanto, mucho más rápida que cualquier solución de Python pura).
Si necesita más control sobre lo que se desinfecta exactamente antes de convertirlo a texto, puede usar explícitamente el Limpiador lxml pasando las opciones que desee en el constructor, por ejemplo:
fuente
El paquete Beautiful Soup hace esto de inmediato por usted.
fuente
Aquí está mi solución para python 3.
No estoy seguro de si es perfecto, pero resolvió mi caso de uso y parece simple.
fuente
Puede usar un analizador HTML diferente ( como lxml o Beautiful Soup ), uno que ofrece funciones para extraer solo texto. O bien, puede ejecutar una expresión regular en su cadena de línea que elimina las etiquetas. Vea los documentos de Python para más información.
fuente
lxml.html.fromstring(s).text_content()
&
. Ej. ) En texto.He usado la respuesta de Eloff con éxito para Python 3.1 [¡muchas gracias!].
Actualicé a Python 3.2.3 y encontré errores.
La solución, proporcionada aquí gracias al respondedor Thomas K, es insertar
super().__init__()
en el siguiente código:... para que se vea así:
... y funcionará para Python 3.2.3.
Nuevamente, ¡gracias a Thomas K por la solución y por el código original de Eloff provisto arriba!
fuente
Puedes escribir tu propia función:
fuente
Las soluciones con HTML-Parser son frágiles, si se ejecutan solo una vez:
resultados en:
lo que pretendes evitar si usa un analizador HTML, cuente las etiquetas hasta que se reemplacen cero:
fuente
html_to_text
e incrusta el texto que sale de esa función dentro de html sin escapar de ese texto, entonces es la falta de escape, que es una vulnerabilidad de seguridad, no lahtml_to_text
función. Lahtml_to_text
función nunca le prometió que el resultado sería texto. E insertar texto en html sin escapar es una vulnerabilidad de seguridad potencial, independientemente de si obtuvo el textohtml_to_text
u otra fuente.Esta es una solución rápida y puede optimizarse aún más, pero funcionará bien. Este código reemplazará todas las etiquetas no vacías con "" y eliminará todas las etiquetas html de un texto de entrada dado. Puede ejecutarlo usando ./file.py input output
fuente
Una adaptación a Python 3 de la respuesta de søren-løvborg
fuente
Para un proyecto, necesitaba tan HTML, pero también css y js. Por lo tanto, hice una variación de la respuesta de Eloff:
fuente
Aquí hay una solución similar a la respuesta actualmente aceptada ( https://stackoverflow.com/a/925630/95989 ), excepto que usa la
HTMLParser
clase interna directamente (es decir, sin subclases), lo que la hace significativamente más breve:fuente
Estoy analizando los archivos Léame de Github y encuentro que lo siguiente realmente funciona bien:
Y entonces
Elimina todas las rebajas y html correctamente.
fuente
Usando BeautifulSoup, html2text o el código de @Eloff, la mayoría de las veces, quedan algunos elementos html, código javascript ...
Por lo tanto, puede usar una combinación de estas bibliotecas y eliminar el formato de descuento (Python 3):
Funciona bien para mí, pero puede mejorarse, por supuesto ...
fuente
Código simple! Esto eliminará todo tipo de etiquetas y contenido dentro de él.
Pero no dará un resultado completo si el texto contiene símbolos <> dentro de él.
fuente
fuente
Este método funciona perfectamente para mí y no requiere instalaciones adicionales:
fuente