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

Python将html转换为文本并模拟格式,python,html,beautifulsoup,Python,Html,Beautifulsoup,我正在学习BeautifulSoup,发现了许多“html2text”解决方案,但我正在寻找的解决方案应该与格式类似: <ul> <li>One</li> <li>Two</li> </ul> 及 我在看文件,但我没有看到任何直接的东西。有什么帮助吗?我愿意使用beautifulsoup以外的其他工具。看看Aaron Swartz的脚本(可以通过pip install html2text安装)。请注意,输出是有效的。如果出

我正在学习BeautifulSoup,发现了许多“html2text”解决方案,但我正在寻找的解决方案应该与格式类似:

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


我在看文件,但我没有看到任何直接的东西。有什么帮助吗?我愿意使用beautifulsoup以外的其他工具。

看看Aaron Swartz的脚本(可以通过
pip install html2text
安装)。请注意,输出是有效的。如果出于某些原因,这并不完全适合您,那么一些非常琐碎的调整应该可以让您获得问题中的确切输出:

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
[1]中的
:导入html2text
在[2]:h1=“”
    …:
  • 一个
  • …:
  • 两个
  • …:
“”“ 在[3]中:打印html2text.html2text(h1) *一个 *两个 在[4]:h2=“”某些文本中 ...: …:这里有更精彩的文字 ...: …:最终文本 [5]中:打印html2text.html2text(h2) 一些文本 >这里有更精彩的文字 最后文本
我有一个更简单任务的代码:删除HTML标记,并在适当的位置插入换行符。也许这可以成为你的一个起点

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

类HTMLTOL(对象):
"""
处理HTML的算法。
"""
#正则表达式来识别HTML的不同部分。
#内部样式表或JavaScript
script_sheet=re.compile(r.“*?()”,
re.IGNORECASE | re.DOTALL)
#HTML注释-可以包含“>”
comment=re.compile(r“”,re.DOTALL)
#HTML标记:
tag=re.compile(r“”,re.DOTALL)
#连续空白字符
nwhites=re.compile(r“[\s]+”)
# ,
标记和关联的结束标记 p_div=重新编译(r“”, re.IGNORECASE | re.DOTALL) #连续的空格,但没有换行符 nspace=re.compile(“[^\S\n]+”,re.UNICODE) #至少两个连续换行 n2ret=re.compile(“\n\n+”) #返回后接空格 retspace=re.compile(“(\n)”) #用于将HTML实体转换为unicode html_parser=HTMLParser.HTMLParser() @静力学方法 def到_nice_文本(html): “”“删除所有HTML标记,但生成格式良好的文本。”“” 如果html为无: 返回u“” text=unicode(html) text=HtmlTool.script\u sheet.sub(“,text) text=HtmlTool.comment.sub(“,text) text=HtmlTool.nwhites.sub(“,text”) text=HtmlTool.p_div.sub(“\n”,text)#将,
转换为“\n” text=HtmlTool.tag.sub(“,text)#删除所有标记 text=HtmlTool.html\u parser.unescape(text) #正确使用空格 text=HtmlTool.nspace.sub(“,text”) text=HtmlTool.retspace.sub(“\n”,text) text=HtmlTool.n2ret.sub(“\n\n”,text) text=text.strip() 返回文本

代码中可能还有一些多余的正则表达式。

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

由于它的简单性质,您无法像使用Beautiful Soup(例如兄弟节点、子节点、父节点等)那样在HTML树中导航,但对于像您这样的简单情况,这就足够了

在您的情况下,只要遇到特定类型的开始标记或结束标记,就可以这样使用它,方法是添加适当的格式:

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))
从html.parser导入HTMLParser
从操作系统导入linesep
类MyHtmlPasser(HtmlPasser):
定义初始化(自):
HtmlPasser.\uuuuu初始化(self,strict=False)
def提要(自身,以html格式):
self.output=“”
super(MyHTMLParser,self).feed(在html中)
返回自输出
def句柄_数据(自身、数据):
self.output+=data.strip()
def句柄\u开始标记(自身、标记、属性):
如果标记=='li':
self.output+=linesep+'*'
elif标记=='blockquote':
self.output+=linesep+linesep+'\t'
def handle_endtag(self,tag):
如果标记=='blockquote':
self.output+=linesep+linesep
parser=MyHTMLParser()
content=“
  • 一个
  • 两个
    • ” 打印(linesep+“示例1:”) 打印(parser.feed(content)) content=“Some text此处有更精彩的文本最终文本” 打印(linesep+“示例2:”) 打印(parser.feed(content))
在使用samaspin的解决方案时,如果存在非英语unicode字符,则解析器停止工作,只返回一个空字符串。为每个循环初始化解析器可确保即使解析器对象损坏,也不会为后续的解析器返回空字符串。将

标记的处理添加到samaspin的解决方案中。 为了处理HTML代码而不清除HTML标记,可以添加后续标记,并将其预期输出写入函数
handle\u starttag

            class MyHTMLParser(HTMLParser):
            """
            This class will be used to clean the html tags whilst ensuring the
            format is maintained. Therefore all the whitespces, newlines, linebrakes, etc are
            converted from html tags to their respective counterparts in python.

            """

            def __init__(self):
                HTMLParser.__init__(self)

            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'
                elif tag == 'br':
                    self.output += linesep + '\n'

            def handle_endtag(self, tag):
                if tag == 'blockquote':
                    self.output += linesep + linesep


        parser = MyHTMLParser()

你想要一些能将html标记转换成降价格式的东西吗?考虑到图像、链接,尤其是以/开头的本地链接,他自己网站上的例子看起来一点都不友好。也许我需要更好地理解降价,但是你能提供一个建议调整的例子吗?或者这是html2text函数中的硬编码?@Mikhail——我不确定我是否遵循——您希望如何处理链接、图像?假设图像被忽略,并且链接的格式为
text(link)
他的网站目前已关闭,所以我无法向您提供详细信息。
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
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
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))
            class MyHTMLParser(HTMLParser):
            """
            This class will be used to clean the html tags whilst ensuring the
            format is maintained. Therefore all the whitespces, newlines, linebrakes, etc are
            converted from html tags to their respective counterparts in python.

            """

            def __init__(self):
                HTMLParser.__init__(self)

            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'
                elif tag == 'br':
                    self.output += linesep + '\n'

            def handle_endtag(self, tag):
                if tag == 'blockquote':
                    self.output += linesep + linesep


        parser = MyHTMLParser()