Как удалить текст между <script>и </script> с помощью Python? - PullRequest
5 голосов
/ 08 июня 2009

как удалить текст между <script> и </script>, используя python?

Ответы [ 9 ]

25 голосов
/ 08 июня 2009

Вы можете использовать BeautifulSoup с этим (и другими) методами:

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

Это фактически удаляет узлы из HTML. Если вы хотите оставить пустые теги <script></script>, вам придется работать с атрибутами item, а не просто извлекать их из супа.

5 голосов
/ 08 июня 2009

Вы пытаетесь предотвратить XSS ? Простое удаление тегов <script> не решит все возможные атаки! Вот большой список многих способов (некоторые из которых очень креативны), которыми вы можете быть уязвимы http://ha.ckers.org/xss.html. Прочитав эту страницу, вы должны понять, почему простое исключение тегов <script> с помощью регулярного выражения недостаточно надежно. В библиотеке python lxml есть функция, которая надежно очистит ваш HTML, чтобы сделать его безопасным для отображения.

Если , вы уверены, что хотите просто удалить теги <script>, которые должен работать в lxml:

from lxml.html import parse

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

Примечание: Я отклонил все решения, используя регулярные выражения. Вот почему вы не должны анализировать HTML с помощью регулярных выражений: Использование регулярных выражений для анализа HTML: почему бы и нет?

Примечание 2: Еще один вопрос SO, показывающий HTML, который невозможно проанализировать с помощью регулярных выражений: Можете ли вы привести некоторые примеры того, почему трудно анализировать XML и HTML с помощью регулярного выражения?

0 голосов
/ 08 июня 2009

Элементное дерево - лучший простой и приятный пакет для этого. Да, есть и другие способы сделать это; но не используйте, потому что они отстой! (через Марка Пилигрима)

0 голосов
/ 08 июня 2009

Согласно ответам, опубликованным Pev и wr, почему бы не обновить регулярное выражение, например ::

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

(? Is) - добавлено, чтобы игнорировать регистр и разрешать новые строки в тексте. Эта версия также должна поддерживать теги сценария с атрибутами.

РЕДАКТИРОВАТЬ: Я пока не могу добавлять комментарии, поэтому я просто редактирую свой ответ. Я полностью согласен с комментарием ниже, регулярные выражения совершенно не подходят для таких задач и б. суп от lxml намного лучше. Но заданный вопрос дал только простой пример, и регулярных выражений должно быть достаточно для такой простой задачи. Использовать Beautiful Soup для простого удаления текста может быть слишком много (перегрузка? Я не могу выразить то, что имею в виду, извините за мой английский).

Кстати, я ошибся, код должен выглядеть так:

pattern = r"(?is)(<script[^>]*>)(.*?)(</script>)"
text = """<script>foo bar  
baz bar foo  </script>"""
re.sub(pattern, '\1\3', text)
0 голосов
/ 08 июня 2009

Если вы не хотите импортировать какие-либо модули:

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)
0 голосов
/ 08 июня 2009
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.'
0 голосов
/ 08 июня 2009

Если вы удаляете все между <script> и </script>, почему бы просто не удалить весь узел?

Вы ожидаете src и body в стиле resig?

0 голосов
/ 08 июня 2009

Я не знаю Python достаточно хорошо, чтобы сказать вам решение. Но если вы хотите использовать это для очистки пользовательского ввода, вы должны быть очень, очень осторожны. Удаление вещей между и просто не все поймать. Может быть, вы можете взглянуть на существующие решения (я предполагаю, что Django включает что-то вроде этого).

0 голосов
/ 08 июня 2009

Вы можете сделать это с помощью модуля HTMLParser (сложный) или использовать регулярные выражения:

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]:]

РЕДАКТИРОВАТЬ: re.DOTALL, благодаря tgray

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...