Подтвердить что ты не робот

Код 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 +

Как я могу это сделать?

4b9b3361

Ответ 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