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

欢迎你!:)

其他回答

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

2020年更新

使用Mozilla Bleach库,它确实允许您自定义保留哪些标记和保留哪些属性,并且还可以根据值过滤属性

这里有两个例子来说明

1)不允许任何HTML标签或属性

获取原始文本样本

raw_text = """
<p><img width="696" height="392" src="https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-768x432.jpg" class="attachment-medium_large size-medium_large wp-post-image" alt="Ethereum Classic 51% Attack: Okex Crypto Exchange Suffers $5.6 Million Loss, Contemplates Delisting ETC" style="float:left; margin:0 15px 15px 0;" srcset="https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-768x432.jpg 768w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-300x169.jpg 300w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-1024x576.jpg 1024w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-696x392.jpg 696w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-1068x601.jpg 1068w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-747x420.jpg 747w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-190x107.jpg 190w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-380x214.jpg 380w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-760x428.jpg 760w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc.jpg 1280w" sizes="(max-width: 696px) 100vw, 696px" />Cryptocurrency exchange Okex reveals it suffered the $5.6 million loss as a result of the double-spend carried out by the attacker(s) in Ethereum Classic 51% attack. Okex says it fully absorbed the loss as per its user-protection policy while insisting that the attack did not cause any loss to the platform&#8217;s users. Also as part [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://news.bitcoin.com/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc/">Ethereum Classic 51% Attack: Okex Crypto Exchange Suffers $5.6 Million Loss, Contemplates Delisting ETC</a> appeared first on <a rel="nofollow" href="https://news.bitcoin.com">Bitcoin News</a>.</p> 
"""

2)从原始文本中删除所有HTML标签和属性

# DO NOT ALLOW any tags or any attributes
from bleach.sanitizer import Cleaner
cleaner = Cleaner(tags=[], attributes={}, styles=[], protocols=[], strip=True, strip_comments=True, filters=None)
print(cleaner.clean(raw_text))

输出

Cryptocurrency exchange Okex reveals it suffered the $5.6 million loss as a result of the double-spend carried out by the attacker(s) in Ethereum Classic 51% attack. Okex says it fully absorbed the loss as per its user-protection policy while insisting that the attack did not cause any loss to the platform&#8217;s users. Also as part [&#8230;]
The post Ethereum Classic 51% Attack: Okex Crypto Exchange Suffers $5.6 Million Loss, Contemplates Delisting ETC appeared first on Bitcoin News. 

3只允许带有srcset属性的img标签

from bleach.sanitizer import Cleaner
# ALLOW ONLY img tags with src attribute
cleaner = Cleaner(tags=['img'], attributes={'img': ['srcset']}, styles=[], protocols=[], strip=True, strip_comments=True, filters=None)
print(cleaner.clean(raw_text))

输出

<img srcset="https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-768x432.jpg 768w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-300x169.jpg 300w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-1024x576.jpg 1024w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-696x392.jpg 696w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-1068x601.jpg 1068w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-747x420.jpg 747w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-190x107.jpg 190w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-380x214.jpg 380w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc-760x428.jpg 760w, https://news.bitcoin.com/wp-content/uploads/2020/08/ethereum-classic-51-attack-okex-crypto-exchange-suffers-5-6-million-loss-contemplates-delisting-etc.jpg 1280w">Cryptocurrency exchange Okex reveals it suffered the $5.6 million loss as a result of the double-spend carried out by the attacker(s) in Ethereum Classic 51% attack. Okex says it fully absorbed the loss as per its user-protection policy while insisting that the attack did not cause any loss to the platform&#8217;s users. Also as part [&#8230;]
The post Ethereum Classic 51% Attack: Okex Crypto Exchange Suffers $5.6 Million Loss, Contemplates Delisting ETC appeared first on Bitcoin News. 

如果您需要剥离HTML标记来进行文本处理,那么一个简单的正则表达式就可以了。如果您希望清除用户生成的HTML以防止XSS攻击,请不要使用此方法。删除所有<script>标签或跟踪<img>s不是一个安全的方法。下面的正则表达式将相当可靠地剥离大多数HTML标记:

import re

re.sub('<[^<]+?>', '', text)

对于那些不理解regex的人来说,这将搜索字符串<…>,其中内部内容由一个或多个不是<的(+)字符组成。的吗?意味着它将匹配它能找到的最小字符串。例如,给定<p>Hello</p>,它将分别用?匹配<'p>和</p>。没有它,它将匹配整个字符串<..Hello..>。

如果非标签<出现在html(例如。2 < 3),它应该被写成转义序列&…总之,^<可能是不必要的。

import re

def remove(text):
    clean = re.compile('<.*?>')
    return re.sub(clean, '', text)

短版!

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的。