2009-06-08 11 views

risposta

0

Si può fare questo con il HTMLParser modulo (complicato) o utilizzare le espressioni regolari:

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, grazie alla tgray

+4

Questo ha molti potenziali problemi riguardanti cose come caso, se il tag script ha attributi, eventualmente parti di testo sfuggite, ecc. È piuttosto difficile coprire tutte le opzioni in modo affidabile rendendo molto più facile l'utilizzo di , testato, librerie come Beautiful Soup. – mavnn

+0

È possibile aggiungere il flag re.DOTALL/re.S alla ricerca in modo che il carattere 'punto' corrisponda a una nuova riga. Senza questo, non si abbineranno blocchi di script che si estendono su più righe (che sono la maggior parte di esse). – tgray

+0

Sfortunato che una risposta legittima venga votata; Questo soddisfa di sicuro le specifiche necessarie. non lo è –

-1

Non so Python abbastanza buono da raccontare tu una soluzione. Ma se vuoi usarlo per disinfettare l'input dell'utente devi essere molto, molto attento. Rimuovere le cose tra e non cattura tutto. Forse puoi dare un'occhiata alle soluzioni esistenti (presumo che Django includa qualcosa come questo).

25

È possibile utilizzare BeautifulSoup con questo (e altri) i metodi:

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

Questo rimuove effettivamente i nodi del HTML. Se si desidera lasciare i tag vuoti <script></script>, sarà necessario lavorare con gli attributi item anziché estrarlo dalla zuppa.

+6

Questa è la risposta giusta. Niloy, o chiunque stia leggendo questa domanda, per favore ignori qualsiasi delle risposte che propongono di usare espressioni regolari in questo caso poiché hanno tutti _serious_, problemi di sicurezza facilmente sfruttabili. –

+0

Sono d'accordo con @DrJokepu. Non cercare di analizzare HTML con espressioni regolari! – user27478

+1

Non riesco a farlo funzionare perché il testo tra il tag dello script contiene cose come: 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

Nota che (. * $)") A prenderla. –

-1

Se non si desidera importare tutti i moduli:

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

di nuovo, che ne dici di lol'; eccetera? –

+1

Bene, ha detto "". – sqram

0

Secondo risposte postato da Pev e wr, perché non aggiornare un'espressione regolare, ad esempio:

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

(? È) - aggiunto per ignorare il caso e consentire nuove righe nel testo. Questa versione dovrebbe anche supportare tag di script con attributi.

EDIT: Non riesco ancora ad aggiungere alcun commento, quindi sto solo modificando la mia risposta. Sono completamente d'accordo con il commento qui sotto, le regex sono totalmente sbagliate per tali compiti eb. la zuppa di lxml è molto meglio. Ma la domanda posta dava solo un semplice esempio e le espressioni regolari dovrebbero essere sufficienti per un compito così semplice. Usare Beautiful Soup per una semplice rimozione del testo potrebbe essere troppo (sovraccarico? Non so come esprimere ciò che intendo, scusa il mio inglese).

BTW ho fatto un errore, il codice dovrebbe essere simile a questo:

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

Che dire di ipt>/* script diabolico viene qui */? Utilizzare espressioni regolari in questo caso è semplicemente sbagliato, secondo me. È troppo facile da aggirare. –

5

Stai cercando di evitare che XSS? L'eliminazione dei tag <script> non risolverà tutti i possibili attacchi! Ecco una grande lista dei molti modi (alcuni dei quali molto creativi) che potresti essere vulnerabile http://ha.ckers.org/xss.html. Dopo aver letto questa pagina dovresti capire perché la semplice eliminazione dei tag <script> usando un'espressione regolare non è abbastanza solida. La libreria python lxml ha una funzione che pulisce in modo robusto il tuo HTML per renderlo sicuro da visualizzare.

Se si è certi che si desidera solo per eliminare i tag <script> questo codice in lxml dovrebbe funzionare:

from lxml.html import parse 

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

Nota: Ho downvoted tutte le soluzioni che utilizzano expresions regolari. Vedi qui il motivo per cui non si dovrebbe analizzare HTML usando le espressioni regolari: Using regular expressions to parse HTML: why not?

Nota 2: Un'altra domanda SO mostrando HTML che è impossibile da analizzare con le espressioni regolari: Can you provide some examples of why it is hard to parse XML and HTML with a regex?

0

Element Tree è il migliore e più semplice pacchetto più dolce per fare questo. Sì, ci sono altri modi per farlo anche tu; ma non usare nessun 'coz che fanno schifo! (via Mark Pilgrim)

Problemi correlati