2009-06-08 37 views

Respuesta

0

Usted puede hacer esto con el módulo de HTMLParser (complicado) o utilizar expresiones regulares:

import re 
content = "asdf <script> bla </script> end" 
x=re.search("<script>.*?</script>", content, re.DOTALL) 
span = x.span() # gives (5, 27) 

stripped_content = content[:span[0]] + content[span[1]:] 

EDIT: re.DOTALL, gracias a tgray

+4

Esto tiene muchos problemas potenciales con respecto a cosas como el caso, si la etiqueta del script tiene atributos, posiblemente fragmentos de texto escapados, etc. Es bastante difícil cubrir todas las opciones de manera confiable haciendo que sea mucho más fácil usar , probado, bibliotecas como Beautiful Soup. – mavnn

+0

Es posible que desee agregar el indicador re.DOTALL/re.S a su búsqueda para que el carácter 'punto' coincida con las líneas nuevas. Sin esto, no coincidirá con los bloques de scripts que abarcan varias líneas (que son la mayoría de ellos). – tgray

+0

Desafortunado que una respuesta legítima se baja votó; Esto cumple con las especificaciones necesarias con seguridad. no es –

-1

No sé Python lo suficientemente bueno para contar usted una solución. Pero si quiere usar eso para desinfectar la entrada del usuario, debe ser muy, muy cuidadoso. Eliminar cosas entre y simplemente no atrapa todo. Tal vez puedas echarle un vistazo a las soluciones existentes (supongo que Django incluye algo como esto).

25

Puede utilizar BeautifulSoup con este (y otros) métodos:

soup = BeautifulSoup(source.lower()) 
to_extract = soup.findAll('script') 
for item in to_extract: 
    item.extract() 

En realidad, esto elimina los nodos del HTML. Si desea dejar las etiquetas <script></script> vacías, tendrá que trabajar con los atributos item en lugar de extraerlo de la sopa.

+6

Esta es la respuesta correcta. Niloy, o cualquier persona que lea esta pregunta, ignore cualquiera de las respuestas que defienden el uso de expresiones regulares en este caso, ya que todas tienen _serious_, problemas de seguridad fácilmente explotables. –

+0

Estoy de acuerdo con @DrJokepu. ¡No intente analizar HTML con expresiones regulares! – user27478

+1

No puedo hacer que esto funcione porque el texto entre la etiqueta del script contiene cosas como: var str = "

-1
example_text = "This is some text <script> blah blah blah </script> this is some more text." 

import re 
myre = re.compile("(^.*)<script>(.*)</script>(.*$)") 
result = myre.match(example_text) 
result.groups() 
    <52> ('This is some text ', ' blah blah blah ', ' this is some more text.') 

# Text between <script> .. </script> 
result.group(2) 
    <56> 'blah blah blah' 

# Text outside of <script> .. </script> 
result.group(1)+result.group(3) 
    <57> 'This is some text this is some more text.' 
+3

Tenga en cuenta que (. * $)") Para Atrapalo. –

-1

Si no desea importar cualquier módulo:

string = "<script> this is some js. begone! </script>" 

string = string.split(' ') 

for i, s in enumerate(string): 
    if s == '<script>' or s == '</script>' : 
     del string[i] 

print ' '.join(string) 
+2

otra vez, ¿qué tal lol'; etc? –

+1

Bueno, dijo "". – sqram

0

Según respuestas publicadas por Pev y WR, ¿por qué no actualizar una expresión regular, por ejemplo:

pattern = r"(?is)<script[^>]*>(.*?)</script>" 
text = """<script>foo bar 
baz bar foo </script>""" 
re.sub(pattern, '', text) 

(? Es) - agregado para ignorar el caso y permitir nuevas líneas en el texto. Esta versión también debería admitir etiquetas de script con atributos.

EDIT: Todavía no puedo agregar ningún comentario, así que solo estoy editando mi respuesta. Estoy totalmente de acuerdo con el siguiente comentario, las expresiones regulares son totalmente incorrectas para tales tareas y b. sopa de lxml son mucho mejores. Pero la pregunta hecha dio solo un ejemplo y las expresiones regulares deberían ser suficientes para una tarea tan simple. Usar Beautiful Soup para eliminar un texto simple podría ser demasiado (¿sobrecarga? No sé cómo expresar lo que quiero decir, disculpe mi inglés).

Por cierto he cometido un error, el código debería tener este aspecto:

pattern = r"(?is)(<script[^>]*>)(.*?)(</script>)" 
text = """<script>foo bar 
baz bar foo </script>""" 
re.sub(pattern, '\1\3', text) 
+3

¿Qué tal ipt>/* script malvado viene aquí */? Usar expresiones regulares en este caso es simplemente incorrecto, en mi opinión. Demasiado fácil de eludir. –

5

¿Estás tratando de evitar que XSS? ¡Solo eliminar las etiquetas <script> no resolverá todos los posibles ataques! Aquí hay una gran lista de las muchas maneras (algunas de ellas muy creativas) de que podrías ser vulnerable http://ha.ckers.org/xss.html. Después de leer esta página, debe comprender por qué la eliminación de las etiquetas <script> utilizando una expresión regular no es lo suficientemente sólida. La biblioteca de Python lxml tiene una función que limpiará robustamente su HTML para que sea seguro visualizarlo.

Si está seguro de que lo que desea es eliminar las etiquetas <script> este código en lxml debería funcionar:

from lxml.html import parse 

root = parse(filename_or_url).getroot() 
for element in root.iter("script"): 
    element.drop_tree() 

Nota: I downvoted todas las soluciones utilizando expresiones regulares. Ve aquí por qué no debe analizar HTML usando expresiones regulares: Using regular expressions to parse HTML: why not?

Nota 2: Otra cuestión de forma que muestra HTML que es imposible analizar con expresiones regulares: Can you provide some examples of why it is hard to parse XML and HTML with a regex?

0

Element Tree es la mejor y más simple paquete más dulce para hacer esto. Sí, hay otras formas de hacerlo también; ¡pero no uses ningún 'porque ellos chupen! (a través de Mark Pilgrim)

Cuestiones relacionadas