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',等等。该怎么做呢?


当前回答

# This is a regex solution.
import re
def removeHtml(html):
  if not html: return html
  # Remove comments first
  innerText = re.compile('<!--[\s\S]*?-->').sub('',html)
  while innerText.find('>')>=0: # Loop through nested Tags
    text = re.compile('<[^<>]+?>').sub('',innerText)
    if text == innerText:
      break
    innerText = text

  return innerText.strip()

其他回答

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

import re

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

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

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

基于lxml.html的解决方案(lxml是一个原生库,比纯python解决方案性能更好)。

要安装lxml模块,使用pip install lxml

移除所有标签

from lxml import html


## from file-like object or URL
tree = html.parse(file_like_object_or_url)

## from string
tree = html.fromstring('safe <script>unsafe</script> safe')

print(tree.text_content().strip())

### OUTPUT: 'safe unsafe safe'

删除预消毒HTML的所有标签(删除一些标签)

from lxml import html
from lxml.html.clean import clean_html

tree = html.fromstring("""<script>dangerous</script><span class="item-summary">
                            Detailed answers to any questions you might have
                        </span>""")

## text only
print(clean_html(tree).text_content().strip())

### OUTPUT: 'Detailed answers to any questions you might have'

还请参阅http://lxml.de/lxmlhtml.html#cleaning-up-html了解lxml. xml的具体内容。清洁。

如果你需要更多的控制哪些特定的标签应该在转换为文本之前删除,然后创建一个自定义的lxml Cleaner与所需的选项,例如:

cleaner = Cleaner(page_structure=True,
                  meta=True,
                  embedded=True,
                  links=True,
                  style=True,
                  processing_instructions=True,
                  inline_style=True,
                  scripts=True,
                  javascript=True,
                  comments=True,
                  frames=True,
                  forms=True,
                  annoying_tags=True,
                  remove_unknown_tags=True,
                  safe_attrs_only=True,
                  safe_attrs=frozenset(['src','color', 'href', 'title', 'class', 'name', 'id']),
                  remove_tags=('span', 'font', 'div')
                  )
sanitized_html = cleaner.clean_html(unsafe_html)

要自定义如何生成纯文本,您可以使用lxml.etree.tostring而不是text_content():

from lxml.etree import tostring

print(tostring(tree, method='text', encoding=str))

你可以使用BeautifulSoup get_text()特性。

from bs4 import BeautifulSoup

html_str = '''
<td><a href="http://www.fakewebsite.example">Please can you strip me?</a>
<br/><a href="http://www.fakewebsite.example">I am waiting....</a>
</td>
'''
soup = BeautifulSoup(html_str)

print(soup.get_text())
#or via attribute of Soup Object: print(soup.text)

建议显式地指定解析器,例如BeautifulSoup(html_str, features="html.parser"),以便输出可重现。

如果你需要保留HTML实体(即&),我在Eloff的答案中添加了“handle_entityref”方法。

from HTMLParser import HTMLParser

class MLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.fed = []
    def handle_data(self, d):
        self.fed.append(d)
    def handle_entityref(self, name):
        self.fed.append('&%s;' % name)
    def get_data(self):
        return ''.join(self.fed)

def html_to_text(html):
    s = MLStripper()
    s.feed(html)
    return s.get_data()

对于一个项目,我需要这样剥离HTML,但也css和js。因此,我对eloff的回答做了一个变化:

class MLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.strict = False
        self.convert_charrefs= True
        self.fed = []
        self.css = False
    def handle_starttag(self, tag, attrs):
        if tag == "style" or tag=="script":
            self.css = True
    def handle_endtag(self, tag):
        if tag=="style" or tag=="script":
            self.css=False
    def handle_data(self, d):
        if not self.css:
            self.fed.append(d)
    def get_data(self):
        return ''.join(self.fed)

def strip_tags(html):
    s = MLStripper()
    s.feed(html)
    return s.get_data()