Код Python для удаления тегов HTML из строки
У меня есть такой текст:
text = """<div>
<h1>Title</h1>
<p>A long text........ </p>
<a href=""> a link </a>
</div>"""
используя чистый Python, без внешнего модуля я хочу иметь это:
>>> print remove_tags(text)
Title A long text..... a link
Я знаю, что могу это сделать, используя lxml.html.fromstring(text).text_content(), но мне нужно добиться того же самого в чистом Python, используя встроенную или std-библиотеку для 2.6 +
Как я могу это сделать?
Ответы
Ответ 1
Используя регулярное выражение
Используя регулярные выражения, вы можете очистить все внутри <>
:
import re
def cleanhtml(raw_html):
cleanr = re.compile('<.*?>')
cleantext = re.sub(cleanr, '', raw_html)
return cleantext
Некоторые HTML-тексты также могут содержать сущности, которые не заключены в квадратные скобки, например ' &nsbm
'. Если это так, то вы можете написать регулярное выражение как
cleanr = re.compile('<.*?>|&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-f]{1,6});')
Эта ссылка содержит более подробную информацию об этом.
Использование BeautifulSoup
Вы также можете использовать дополнительный пакет BeautifulSoup
, чтобы узнать весь необработанный текст
При вызове BeautifulSoup вам нужно будет явно установить синтаксический анализатор. Я рекомендую использовать "lxml", как указано в альтернативных ответах (гораздо более надежный, чем стандартный (то есть доступный без дополнительной установки) "html.parser".
from bs4 import BeautifulSoup
cleantext = BeautifulSoup(raw_html, "lxml").text
Но это не мешает вам использовать внешние библиотеки, поэтому я рекомендую первое решение.
Ответ 2
Python имеет несколько встроенных XML-модулей. Самый простой для случая, когда у вас уже есть строка с полным HTML, xml.etree
, которая работает (несколько ) аналогично примеру lxml, который вы указываете:
def remove_tags(text):
return ''.join(xml.etree.ElementTree.fromstring(text).itertext())
Ответ 3
Обратите внимание, что это не идеально, так как если бы у вас было что-то вроде, скажем, <a title=">">
это <a title=">">
бы. Тем не менее, это самое близкое к небиблиотечному Python без действительно сложной функции:
import re
TAG_RE = re.compile(r'<[^>]+>')
def remove_tags(text):
return TAG_RE.sub('', text)
Однако, как упоминает xml.etree
доступен в стандартной библиотеке Python, так что вы, вероятно, можете просто адаптировать его для использования в качестве существующей версии lxml
:
def remove_tags(text):
return ''.join(xml.etree.ElementTree.fromstring(text).itertext())
Ответ 4
Существует простой способ сделать это на любом C-подобном языке. Стиль не Pythonic, но работает с чистым Python:
def remove_html_markup(s):
tag = False
quote = False
out = ""
for c in s:
if c == '<' and not quote:
tag = True
elif c == '>' and not quote:
tag = False
elif (c == '"' or c == "'") and tag:
quote = not quote
elif not tag:
out = out + c
return out
Идея основана на простом автомате с конечным числом состояний и подробно описана здесь: http://youtu.be/2tu9LTDujbw
Вы можете увидеть это работает здесь: http://youtu.be/HPkNPcYed9M?t=35s
PS - Если вы заинтересованы в классе (об умной отладке с python), я дам вам ссылку: https://www.udacity.com/course/software-debugging--cs259. Это бесплатно!
Ответ 5
global temp
temp =''
s = ' '
def remove_strings(text):
global temp
if text == '':
return temp
start = text.find('<')
end = text.find('>')
if start == -1 and end == -1 :
temp = temp + text
return temp
newstring = text[end+1:]
fresh_start = newstring.find('<')
if newstring[:fresh_start] != '':
temp += s+newstring[:fresh_start]
remove_strings(newstring[fresh_start:])
return temp