from mechanize import Browser
br = Browser()
br.open('http://somewebpage')
html = br.response().readlines()
for line in html:
print line
在HTML文件中打印一行时,我试图找到一种方法来只显示每个HTML元素的内容而不是格式本身 . 如果找到 '<a href="whatever.com">some text</a>'
,它只会打印'some text', '<b>hello</b>'
打印'hello'等 . 怎么会这样做呢?
21 回答
您可以使用不同的HTML解析器(like lxml或Beautiful Soup) - 一个提供仅提取文本的函数的解析器 . 或者,您可以在删除标记的行字符串上运行正则表达式 . 有关更多信息,请参阅http://www.amk.ca/python/howto/regex/ .
我总是使用这个函数去除HTML标签,因为它只需要Python stdlib:
在Python 2上
对于Python 3
Note :这仅适用于3.1 . 对于3.2或更高版本,您需要调用父类的 init 函数 . 见Using HTMLParser in Python 3.2
我没想过会错过的案例,但你可以做一个简单的正则表达式:
对于那些不理解正则表达式的人,这将搜索字符串
<...>
,其中内部内容由一个或多个(+
)字符组成,而不是<
.?
表示它将匹配它可以找到的最小字符串 . 例如,给定<p>Hello</p>
,它将<'p>
和</p>
分别与?
匹配 . 没有它,它将匹配整个字符串<..Hello..>
.如果非标签
<
出现在html中(例如2 < 3
),它应该被写为转义序列&...
,所以^<
可能是不必要的 .为什么你们所有人都这么做?您可以使用BeautifulSoup
get_text()
功能 .短版!
Regex source: MarkupSafe . 他们的版本也处理HTML实体,而这个快速版本没有 .
为什么我不能剥离标签并离开?
让人们远离事物是一回事,而不会留下
i
. 但是接受任意输入并使其完全无害是另一回事 . 此页面上的大多数技术都会保留未关闭的注释(<!--
)和不包含标记(blah <<<><blah
)的角括号等内容 . HTMLParser版本甚至可以保留完整的标签,如果它们在未公开的评论中 .如果您的模板是
{{ firstname }} {{ lastname }}
怎么办?firstname = '<a'
和lastname = 'href="http://evil.com/">'
将被此页面上的每个标记剥离器(@Medeiros除外)通过,因为它们不是自己的完整标记 . 剥离普通的HTML标签是不够的 .Django的
strip_tags
,这个问题的最佳答案的改进版(见下一个 Headers ),给出了以下警告:听从他们的建议!
要使用HTMLParser去除标记,您必须多次运行它 .
It's easy to circumvent the top answer to this question.
看看这个字符串(source and discussion):
HTMLParser第一次看到它时,它无法判断
<img...>
是一个标签 . 它看起来很破碎,所以HTMLParser并没有摆脱它 . 它只取出<!-- comments -->
,留给你这个问题是在2014年3月向Django项目披露的 . 他们的旧版本
strip_tags
与这个问题的最佳答案基本相同 . Their new version基本上在循环中运行它,直到再次运行它不会更改字符串:当然,如果你总是逃避
strip_tags()
的结果,这一切都不是问题 .Update 19 March, 2015 :Django版本在1.4.20,1.6.11,1.7.7和1.8c1之前有一个错误 . 这些版本可能会在strip_tags()函数中进入无限循环 . 固定版本在上面复制 . More details here .
要复制或使用的好东西
我的示例代码不处理HTML实体 - Django和MarkupSafe打包版本 .
我的示例代码是从优秀的MarkupSafe库中提取的,用于防止跨站点脚本编写 . 它's convenient and fast (with C speedups to its native Python version). It'包含在Google App Engine中,由Jinja2 (2.7 and up),Mako,Pylons等使用 . 它可以轻松地与Django 1.7的Django模板一起使用 .
Django的strip_tags和最新版本的其他html实用程序都很好,但我觉得它们不如MarkupSafe方便 . 它们非常独立,你可以从this file复制你需要的东西 .
如果您需要剥离几乎所有标签,Bleach库是好的 . 你可以让它执行像"my users can italicize things, but they can't make iframes."这样的规则
了解标签剥离器的属性!对它进行模糊测试! Here is the code我曾经为这个答案做过研究 .
懦弱的注意事项 - 问题本身是关于打印到控制台,但这是"python strip html from string"的最高谷歌结果,所以这就是为什么这个答案是99%关于网络 .
我需要一种方法来剥离标签并将HTML实体解码为纯文本 . 以下解决方案基于Eloff 's answer (which I couldn' t使用,因为它剥离实体) .
快速测试:
结果:
错误处理:
无效的HTML结构可能会导致HTMLParseError .
无效的命名HTML实体(例如
&#apos;
,在XML和XHTML中有效,但不是纯HTML)将导致ValueError
异常 .指定Python可接受的Unicode范围之外的代码点的数字HTML实体(例如,在某些系统上,Basic Multilingual Plane之外的字符)会导致
ValueError
异常 .Security note: 不要将HTML剥离(将HTML转换为纯文本)与HTML清理(将纯文本转换为HTML)混淆 . 此答案将删除HTML并将实体解码为纯文本 - 这不会使结果在HTML上下文中安全使用 .
示例:
<script>alert("Hello");</script>
将转换为<script>alert("Hello");</script>
,这是100%正确的行为,但如果生成的纯文本按原样插入HTML页面,显然是不够的 .规则并不难:每当您将纯文本字符串插入HTML输出时,即使您"know"它不包含HTML(例如,因为您剥离了HTML内容),您也应始终使用HTML转义它(使用
cgi.escape(s, True)
) .(但是,OP询问是否将结果打印到控制台,在这种情况下不需要HTML转义 . )
Python 3.4+ version: (与doctest!)
请注意,HTMLParser在Python 3中得到了改进(意味着代码更少,错误处理更好) .
有一个简单的方法:
这个想法在这里解释:http://youtu.be/2tu9LTDujbw
你可以在这里看到它:http://youtu.be/HPkNPcYed9M?t=35s
PS - 如果你对这个课感兴趣(关于用python进行智能调试),我给你一个链接:http://www.udacity.com/overview/Course/cs259/CourseRev/1 . 免费!
别客气! :)
如果您需要保留HTML实体(即
&
),我将"handle_entityref"方法添加到Eloff's answer .如果要删除所有HTML标记,我发现的最简单方法是使用BeautifulSoup:
我尝试了接受的答案的代码,但我得到了“RuntimeError:超出最大递归深度”,这与上面的代码块没有发生 .
基于lxml.html的解决方案(lxml是一个本机库,因此比任何纯Python解决方案都快得多) .
如果在转换为文本之前需要更多地控制清理的内容,那么您可能希望通过在构造函数中传递options you want来显式使用lxml Cleaner,例如:
美丽的汤包立即为您做到这一点 .
我已成功使用Eloff的答案用于Python 3.1 [非常感谢!] .
我升级到Python 3.2.3,并遇到了错误 .
由于响应者Thomas K提供的解决方案是将
super().__init__()
插入以下代码中:...为了使它看起来像这样:
...它适用于Python 3.2.3 .
再次感谢Thomas K的修复和上面提供的Eloff的原始代码!
如果HTML-Parser只运行一次,它们都是易碎的:
结果是:
你打算阻止什么 . 如果您使用HTML-Parser,请将标记计数直到零被替换:
这是一个快速修复,可以更加优化,但它会正常工作 . 此代码将用“”替换所有非空标记,并将所有html标记从给定的输入文本中删除 . 您可以使用./file.py输入输出来运行它
søren-løvborg答案的蟒蛇3改编
对于一个项目,我需要这样剥离HTML,还需要css和js . 因此,我做了一个Eloffs的变种回答:
这是一个类似于当前接受的答案(https://stackoverflow.com/a/925630/95989)的解决方案,除了它直接使用内部
HTMLParser
类(即没有子类化),从而使它更加简洁:你可以编写自己的函数:
我正在解析Github自述文件,我发现以下内容确实很有效:
然后
正确删除所有markdown和html .
使用BeautifulSoup,html2text或来自@Eloff的代码,大部分时间,它仍然是一些html元素,javascript代码......
因此,您可以使用这些库的组合并删除markdown格式(Python 3):
它适用于我,但它可以增强,当然......
这种方法对我来说完美无缺,无需额外安装: