from mechanize import Browser
br = Browser()
br.open('http://somewebpage')
html = br.response().readlines()
for line in html:
  print line

当在HTML文件中打印一行时,我试图找到一种方法,只显示每个HTML元素的内容,而不是格式本身。如果它发现'<a href="等等。例如">some text</a>',它只会打印'some text', '<b>hello</b>'打印'hello',等等。该怎么做呢?


当前回答

有一个简单的方法:

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。它是免费的!

欢迎你!:)

其他回答

我已经成功地在Python 3.1中使用了Eloff的答案[非常感谢!]。

我升级到Python 3.2.3,并遇到了错误。

解决方案,这里提供感谢响应器Thomas K,是插入super().__init__()到以下代码:

def __init__(self):
    self.reset()
    self.fed = []

... 为了让它看起来像这样:

def __init__(self):
    super().__init__()
    self.reset()
    self.fed = []

... 它适用于Python 3.2.3。

再次感谢Thomas K的修复和Eloff提供的原始代码!

有一个简单的方法:

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。它是免费的!

欢迎你!:)

这是一个类似于目前接受的答案(https://stackoverflow.com/a/925630/95989)的解决方案,除了它直接使用内部HTMLParser类(即没有子类化),从而使它显着更简洁:

def strip_html(text):
    parts = []                                                                      
    parser = HTMLParser()                                                           
    parser.handle_data = parts.append                                               
    parser.feed(text)                                                               
    return ''.join(parts)

短版!

import re, html
tag_re = re.compile(r'(<!--.*?-->|<[^>]*>)')

# Remove well-formed tags, fixing mistakes by legitimate users
no_tags = tag_re.sub('', user_input)

# Clean up anything else by escaping
ready_for_web = html.escape(no_tags)

Regex来源:MarkupSafe。他们的版本也处理HTML实体,而这个快速的版本不能。

为什么我不能把标签撕掉,然后留下?

这是一件事,让人们远离<i>斜体</i>的东西,而不留下浮动。但任意输入并使其完全无害是另一回事。本页上的大多数技术都将保留未关闭的注释(<!——)和不是标签一部分的尖括号(blah <<<><blah)。HTMLParser版本甚至可以保留完整的标记,如果它们在未关闭的注释中。

如果你的模板是{{firstname}} {{lastname}}呢?Firstname = '<a' and lastname = 'href="http://evil。example/">'将被该页上的每个标签剥离器通过(除了@Medeiros!),因为它们本身不是完整的标签。除去普通的HTML标记是不够的。

Django的strip_tags是这个问题顶部答案的改进版本(见下一个标题),给出了以下警告:

绝对不能保证得到的字符串是HTML安全的。因此,永远不要在没有转义的情况下将strip_tags调用的结果标记为安全,例如使用escape()。

听从他们的建议!

要用HTMLParser去除标签,你必须运行它多次。

绕过这个问题最上面的答案很容易。

看看这个字符串(来源和讨论):

<img<!-- --> src=x onerror=alert(1);//><!-- -->

HTMLParser第一次看到它时,它不能告诉<img…>是一个标签。它看起来坏了,所以HTMLParser不会去掉它。它只去掉<!——评论——>,留给你

<img src=x onerror=alert(1);//>

这个问题是在2014年3月向Django项目披露的。他们的旧strip_tags本质上与这个问题的顶部答案相同。他们的新版本基本上是在循环中运行它,直到再次运行它不会改变字符串:

# _strip_once runs HTMLParser once, pulling out just the text of all the nodes.

def strip_tags(value):
    """Returns the given HTML with all tags stripped."""
    # Note: in typical case this loop executes _strip_once once. Loop condition
    # is redundant, but helps to reduce number of executions of _strip_once.
    while '<' in value and '>' in value:
        new_value = _strip_once(value)
        if len(new_value) >= len(value):
            # _strip_once was not able to detect more tags
            break
        value = new_value
    return value

当然,如果总是转义strip_tags()的结果,这些都不是问题。

2015年3月19日更新:在1.4.20、1.6.11、1.7.7和1.8c1之前的Django版本中有一个错误。这些版本可以在strip_tags()函数中进入一个无限循环。固定版本见上文。详情请点击这里。

好的东西可以复制或使用

我的示例代码不处理HTML实体——Django和MarkupSafe的打包版本可以。

我的示例代码摘自用于防止跨站点脚本编写的优秀MarkupSafe库。它既方便又快速(C会加速到原生Python版本)。它包含在谷歌应用程序引擎中,并被Jinja2(2.7及以上),Mako, Pylons等使用。它可以很容易地与Django 1.7的模板一起工作。

Django最新版本的strip_tags和其他HTML实用程序都不错,但我发现它们不如MarkupSafe方便。它们非常独立,你可以从这个文件中复制你需要的东西。

如果你需要去除几乎所有的标签,Bleach库是很好的选择。你可以让它强制执行这样的规则:“我的用户可以用斜体,但他们不能创建iframe。”

了解标签剥离器的属性!对它进行绒毛测试!这是我用来研究这个答案的代码。

这个问题本身是关于打印到控制台的,但这是“python从字符串中剥离HTML”的排名第一的谷歌结果,所以这就是为什么这个答案99%是关于web的。

您可以使用不同的HTML解析器(如lxml或Beautiful Soup)——它提供只提取文本的函数。或者,您可以在行字符串上运行一个regex来删除标记。请参阅Python文档了解更多信息。