zoukankan      html  css  js  c++  java
  • SGMLParser (二) 分类: python 小练习 HTMLParser 2014-02-20 14:06 362人阅读 评论(0) 收藏

    #coding:utf-8
    from sgmllib import SGMLParser
    '''
    目的:解析出字符串中<div class='entry-content'>下<p>后面的文本内容。(注意字符串中的div含有嵌套的div)

    基本的思路:

        遇到<div class='entry-content'> 设置标记flag = True
        遇到</div>后 设置标记flag = False
        当flag 为True时遇到<p> 设置标记getdata = True
        遇到</p> 且getdata = True,设置getdata = False

    问题:如何判断遇到的</div>是和<div class='entry-content'>匹配的哪个呢?字符串div中含有嵌套的div,解析子div下<p>的文本内容

    解决方法:
    </div>和<div>是对应的,我们可以记录他所处的层数。进入子层div step加1,退出子层div  verbatim减1.这样就可以判断是否是同一层了。

    1.self.div 标记是否遇到了div标签;self.p 标记是否遇到了p标签;self.step 标记遇到div标签的层次,默认是0
    2.第一次遇到<div>标签,则设置self.div=True:
        2.1 如果再遇到<p>标签,则设置self.p=True;只有同时满足self.div=True、self.p=True,才输出文本内容
        2.2 如果再次遇到到<div>标签,则设置self.step+=1,然后遇到</div>结束标签,则self.step -=1,标记跳出子层div

    '''
    class sp(SGMLParser):
        def reset(self):
            '''
            初始化,设置标记变量
            '''
            #标记是否遇到了div标签
            self.div = False
            #标记是否遇到了p标签
            self.p = False
            #标记遇到div标签的层次,默认是0
            self.step = 0

            SGMLParser.reset(self)

        def start_div(self,attr):
            #如果第二次遇到div,此时self.div已经为True,则执行 self.step+=1
            if self.div==True:
                self.step +=1
            for k,v in attr:
                if k=="class" and v=="entry-content":
                    self.div=True

        def end_div(self):
            #如果 self.step !=0,即仍在子div中,则退出子div
            if self.step !=0:
                self.step -=1
                #标记跳出子层div后,return
                return
            #如果仍是第一个div中,则遇到</div>,设置self.div=False,结束div
            self.div=False

        def start_p(self,attr):
            #遇到div中的 <p>标签,设置self.p=True
            if self.div==True:
                self.p=True

        def end_p(self):
            self.p=False

        def handle_data(self,data):
            #只有满足<div>下的<p>标签内容,才输出
            if self.div==True and self.p==True:
                print data.decode("utf-8")

    if __name__ == '__main__':
        the_page ='''  <div class='entry-content'>
        <p>感兴趣内容1</p>
        <p>感兴趣内容2</p>
        ……
        <p>感兴趣内容n</p>
        </div>

        <div class='entry-content'><div>我是来捣乱的<p>感兴趣ing</p></div><p>感兴趣</p></div>

        <div class='content'>
        <p>内容1</p>
        <p>内容2</p>
        ……
        <p>内容n</p>
        </div>
        '''
        s=sp()
        s.feed(the_page)
        s.close()

    '''
    结果:
    感兴趣内容1
    感兴趣内容2
    感兴趣内容n
    感兴趣s
    感兴趣
    '''

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Qt使用QCustomplot绘制曲线--修改纵坐标显示宽度
    为WPF项目添加Program.cs
    error: C1083: 无法打开包括文件: “QApplication”: No such file or directory
    clangbackend已停止工作
    无法处理文件 MinimalSimpleBrowserForm.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记。要想处理这些文件,请删除 Web 标记。
    QByteArray转QString打印
    zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法
    HTML无刷新提交表单
    这个是我得标题:1548241388
    这个是我得标题:1548241357
  • 原文地址:https://www.cnblogs.com/think1988/p/4627936.html
Copyright © 2011-2022 走看看