昨天看到了这篇文章,挺感兴趣的,早就知道python功能很强大,抓取网站信息很方便,一直没有用过,就好好分析了一下,在原作者的基础上修改了一下,也实现了博客园首页信息的提取,主要提取的是关于文章的标题、作者、发布时间、评论、阅读几个属性。
获取不同页面的html数据:
1 import os,urllib,sys 2 class LinkParser: 3 def __init__(self,url): 4 self.urls=[url] 5 for i in range(2,10): 6 self.urls.insert(0,url+'p'+str(i)) 7 8 def getDatas(self): 9 cnt=0 10 while len(self.urls)>=1: 11 x=self.urls.pop() 12 cnt=cnt+1 13 print ('start parser:',x) 14 try: 15 f=urllib.urlopen(x) 16 s=f.read() 17 f.close() 18 fx=open(os.path.join(os.getcwd(),'data','{0}.html'.format('No.'+str(cnt))),'wb') 19 fx.write(s) 20 fx.close() 21 except: 22 print('error',x) 23 print(sys.exc_info()) 24 continue 25 if __name__=="__main__": 26 parser=LinkParser('http://www.cnblogs.com/') 27 parser.getDatas()
解释:定义了LinkParser类,类的初始化需要一个网站,上面给出的就是博客园的网址,通过查看博客园的前台源代码发现,博客园不同的页面就是在'http://www.cnblogs.com/'基础上加p2、p3、p4等等,加p12就是第12页,所以可以循环把你想得到的页面的网址保存到一个数组里面,getDatas()方法就是遍历该数组,把各个网址的前台html数据得到,并保存到相应的文件中,注意要在当前.py文件所在的路径下新建data文件夹。
处理获取的html数据,并且得到自己想要的数据:
1 # -*- coding: utf-8 -*- 2 from HTMLParser import HTMLParser 3 import os,sys 4 class MyHTMLParser(HTMLParser): 5 def __init__(self): 6 HTMLParser.__init__(self) 7 self.flag=0 8 self.title='' 9 self.author='' 10 self.time='' 11 self.comment='' 12 self.view='' 13 self.result=[('题目','作者','发布时间','评论次数','阅读次数')] 14 def handle_starttag(self,tag,attrs): 15 if self.flag==0: 16 if tag=='a': 17 for i in attrs: 18 if i[0]=='class' and i[1]=='titlelnk': 19 self.flag=1 20 elif self.flag==2: 21 if tag=='div': 22 for i in attrs: 23 if i[0]=='class' and i[1]=='post_item_foot': 24 self.flag=3 25 elif self.flag==3: 26 if tag=='a': 27 self.flag=4 28 elif self.flag==5: 29 if tag=='span': 30 for i in attrs: 31 if i[0]=='class' and i[1]=='article_comment': 32 self.flag=6 33 elif self.flag==7: 34 if tag=='span': 35 for i in attrs: 36 if i[0]=='class' and i[1]=='article_view': 37 self.flag=8 38 def handle_data(self,data): 39 if self.flag==1: 40 self.title=data.strip() 41 self.flag=2 42 elif self.flag==4: 43 self.author=data.strip() 44 self.flag=5 45 elif self.flag==5: 46 self.time=data.strip()[-16:] 47 elif self.flag==6: 48 self.comment=data.strip()[7:-1] 49 self.flag=7 50 elif self.flag==8: 51 self.view=data.strip()[7:-1] 52 self.result.append((self.title,self.author,self.time,self.comment,self.view)) 53 self.flag=0 54 def getContent(filename): 55 parser=MyHTMLParser() 56 f=open(os.path.join(os.getcwd(),'data',filename),'r+') 57 s=f.read() 58 f.close() 59 parser.feed(s) 60 f=open(os.path.join(os.getcwd(),'result.txt'),'a') 61 for i in parser.result: 62 f.write('{0} {1} {2} {3} {4} '.format(i[0],i[1],i[2],i[3],i[4])) 63 f.close() 64 if __name__=="__main__": 65 for i in os.listdir(os.path.join(os.getcwd(),'data')): 66 print i 67 getContent(i) 68 input()
前面一步得到了不同页面下的html数据,这一步就是解析数据得到我们想要的信息,用到了HTMLParser类的几个方法,比如handle_starttag(self,tag,attrs)方法,该方法是在遇到html语言中的开始标志时才调用的方法,tag是标签名称,attrs是标签的属性,handle_data(self,data)是遇到html语言中的数据项时调用的方法。
需要注意:该类中的方法只有遇到是属于该方法的属性时才调用,比如下面这是博客园的前台源码,我们怎么得到想要的数据呢?
<div class="post_item_foot"> <a href="http://www.cnblogs.com/wumadi/" class="lightblue">无码帝</a> 发布于 2013-08-22 09:02 <span class="article_comment"><a href="http://www.cnblogs.com/wumadi/p/3270528.html#commentform" title="" class="gray"> 评论(0)</a></span><span class="article_view"><a href="http://www.cnblogs.com/wumadi/p/3270528.html" class="gray">阅读(27)</a></span></div> </div>
分析这段html源码,解析该数据过程:遇到开始标签'div',调用handle_starttag()方法,遇到开始标签'a',调用handle_starttag()方法,遇到内容'无码弟',调用handle_data()方法,继续又遇到内容'发表于 2013-09-22 09:02',又是调用handle_data()方法,接着遇到开始标签'span',调用.....过程就是这样。
最终结果图:
说明:该文章是在转载的作者'ola2010'的文章基础上修改得到的。点击原文链接。感谢该作者。