Python将html转换为文本和模拟格式

2024-05-19 22:10:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习BeautifulGroup,发现了许多“html2text”解决方案,但我要找的应该是模仿格式的:

<ul>
<li>One</li>
<li>Two</li>
</ul>

会变成

* One
* Two

以及

Some text
<blockquote>
More magnificent text here
</blockquote>
Final text

Some text

    More magnificent text here

Final text

我在看医生,但我没有看到任何直接的进展。有什么帮助吗?我很乐意使用美貌以外的东西。


Tags: textheremore格式someli解决方案ul
3条回答

我有一个更简单的任务代码:删除HTML标记,并在适当的位置插入换行符。也许这可以成为你的起点。

Python的textwrap模块可能有助于创建缩进的文本块。

http://docs.python.org/2/library/textwrap.html

class HtmlTool(object):
    """
    Algorithms to process HTML.
    """
    #Regular expressions to recognize different parts of HTML. 
    #Internal style sheets or JavaScript 
    script_sheet = re.compile(r"<(script|style).*?>.*?(</\1>)", 
                              re.IGNORECASE | re.DOTALL)
    #HTML comments - can contain ">"
    comment = re.compile(r"<!--(.*?)-->", re.DOTALL) 
    #HTML tags: <any-text>
    tag = re.compile(r"<.*?>", re.DOTALL)
    #Consecutive whitespace characters
    nwhites = re.compile(r"[\s]+")
    #<p>, <div>, <br> tags and associated closing tags
    p_div = re.compile(r"</?(p|div|br).*?>", 
                       re.IGNORECASE | re.DOTALL)
    #Consecutive whitespace, but no newlines
    nspace = re.compile("[^\S\n]+", re.UNICODE)
    #At least two consecutive newlines
    n2ret = re.compile("\n\n+")
    #A return followed by a space
    retspace = re.compile("(\n )")

    #For converting HTML entities to unicode
    html_parser = HTMLParser.HTMLParser()

    @staticmethod
    def to_nice_text(html):
        """Remove all HTML tags, but produce a nicely formatted text."""
        if html is None:
            return u""
        text = unicode(html)
        text = HtmlTool.script_sheet.sub("", text)
        text = HtmlTool.comment.sub("", text)
        text = HtmlTool.nwhites.sub(" ", text)
        text = HtmlTool.p_div.sub("\n", text) #convert <p>, <div>, <br> to "\n"
        text = HtmlTool.tag.sub("", text)     #remove all tags
        text = HtmlTool.html_parser.unescape(text)
        #Get whitespace right
        text = HtmlTool.nspace.sub(" ", text)
        text = HtmlTool.retspace.sub("\n", text)
        text = HtmlTool.n2ret.sub("\n\n", text)
        text = text.strip()
        return text

代码中可能还有一些多余的regex。

看一看Aaron Swartz的html2text脚本(可以与pip install html2text一起安装)。请注意,输出是有效的Markdown。如果由于某些原因,这不完全适合你,一些相当小的调整应该让你得到你的问题的确切输出:

In [1]: import html2text

In [2]: h1 = """<ul>
   ...: <li>One</li>
   ...: <li>Two</li>
   ...: </ul>"""

In [3]: print html2text.html2text(h1)
  * One
  * Two

In [4]: h2 = """<p>Some text
   ...: <blockquote>
   ...: More magnificent text here
   ...: </blockquote>
   ...: Final text</p>"""

In [5]: print html2text.html2text(h2)
Some text

> More magnificent text here

Final text

Python的内置html.parser(早期版本的HTMLParser)模块可以很容易地扩展,以创建一个简单的翻译程序,您可以根据自己的具体需要进行调整。它允许您在解析器遍历HTML时钩住某些事件。

由于它的简单特性,你不能像使用漂亮的Soup那样在HTML树上导航(例如兄弟节点、子节点、父节点等),但是对于像你这样的简单情况,它应该足够了。

html.parser homepage

在这种情况下,只要遇到特定类型的开始标记或结束标记,就可以通过添加适当的格式来使用它:

from html.parser import HTMLParser
from os import linesep

class MyHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self, strict=False)
    def feed(self, in_html):
        self.output = ""
        super(MyHTMLParser, self).feed(in_html)
        return self.output
    def handle_data(self, data):
        self.output += data.strip()
    def handle_starttag(self, tag, attrs):
        if tag == 'li':
            self.output += linesep + '* '
        elif tag == 'blockquote' :
            self.output += linesep + linesep + '\t'
    def handle_endtag(self, tag):
        if tag == 'blockquote':
            self.output += linesep + linesep

parser = MyHTMLParser()
content = "<ul><li>One</li><li>Two</li></ul>"
print(linesep + "Example 1:")
print(parser.feed(content))
content = "Some text<blockquote>More magnificent text here</blockquote>Final text"
print(linesep + "Example 2:")
print(parser.feed(content))

相关问题 更多 >