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
感兴趣
'''
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
感兴趣
'''
版权声明:本文为博主原创文章,未经博主允许不得转载。