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, используя встроенную или стандартную библиотеку для 2.6+

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

5 ответов

Используя регулярное выражение

Используя регулярные выражения, вы можете очистить все внутри <>:

import re

def cleanhtml(raw_html):
  cleanr = re.compile('<.*?>')
  cleantext = re.sub(cleanr, '', raw_html)
  return cleantext

Использование BeautifulSoup

Вы также можете использовать BeautifulSoup дополнительный пакет, чтобы узнать весь необработанный текст

При вызове BeautifulSoup вам нужно будет явно установить синтаксический анализатор. Я рекомендую "lxml", как указано в альтернативных ответах (гораздо более надежный, чем стандартный (то есть доступный без дополнительной установки) "html.parser"

from bs4 import BeautifulSoup
cleantext = BeautifulSoup(raw_html, "lxml").text

Но это не мешает вам использовать внешние библиотеки, поэтому я рекомендую первое решение.

Python имеет несколько встроенных XML-модулей. Самый простой для случая, когда у вас уже есть строка с полным HTML, это xml.etree, который работает (в некоторой степени) аналогично примеру lxml, который вы упоминаете:

def remove_tags(text):
    return ''.join(xml.etree.ElementTree.fromstring(text).itertext())

Обратите внимание, что это не идеально, так как если у вас было что-то вроде, скажем, <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())

Есть простой способ сделать это на любом 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), я дам вам ссылку: http://www.udacity.com/overview/Course/cs259/CourseRev/1. Это бесплатно!

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
Другие вопросы по тегам