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
感兴趣
'''

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

posted @ 2014-02-20 14:06  前行者2011  阅读(111)  评论(0编辑  收藏  举报