python——博客园首页信息提取与分析
前言
前两天写了博客,然后发到了博客园首页,然后看着点击量一点点上升,感觉怪怪的。
然后就产生了一点好奇:有多少人把博客发表到了首页上?每天博客园首页会发表多少文章?谁发表的文章最多?评论和阅读数量的对应关系是多少?
有了好奇之后,就在想,怎样才能知道答案?
1. 寻路第一步
通过浏览博客园发现,在博客园最多能看到200页。所以,能不能先把这200页给下载下来。之前有写过一篇博客,批量下载图片,所以可以用博客中类似的方法把这些网页下载下来。
from html.parser import HTMLParser import os,urllib.request,sys #通过博客园NEXT按钮,可以获取下一个网页的地址,这样一直循环,就可以将200个网页下载下来。 #setp 1. 通过解析网页,获取下一个网页的地址。 class LinkParser(HTMLParser): def __init__(self,strict=False,domain=''): HTMLParser.__init__(self,strict) self.value='' self.domain=domain self.next=[] def handle_starttag(self,tag,attrs): if tag=='a': for i in attrs: if i[0]=='href': self.value=i[1] def handle_data(self,data): if data.startswith('Next'): if (self.domain!='' )and ('://' not in self.value): self.next.append(self.domain+self.value) else: self.next.append(self.value) #setp 2. 下载当前网页,并根据解析结果,下载下一个网页。 def getLinks(url,domain): doing=[url] done=[] cnt=0; while len(doing)>=1: x=doing.pop(); done.append(x) cnt=cnt+1; print('start:',x) try: f=urllib.request.urlopen(x,timeout=120) s=f.read() f.close() fx=open(os.path.join(os.getcwd(),'data','{0}.html'.format(str(cnt))),'wb') #需要在当前目录建立data文件夹 fx.write(s) fx.close() parser=LinkParser(strict=False,domain=domain) parser.feed(s.decode()) for i in parser.next: if i not in done: doing.insert(0,i) parser.next=[] print('ok:',x) except: print('error:',x) print(sys.exc_info()) continue return done if __name__=='__main__': getLinks('http://www.cnblogs.com/','http://www.cnblogs.com/')
2. 从网页抽取信息
网页已经下载下来了,现在需要把信息从网页上抽取出来。
经过分析,每个网页上列出了20条记录,每条记录包含标题,作者,发布时间,推荐等信息。
怎样把这些给抽取出来呢?
先写一个小的程序,看看Python是怎么解析这些数据的:
数据:
<html> <head></head> <body> <div class="post_item"> <div class="digg"> <div class="diggit" onclick="DiggIt(3266366,130739,1)"> <span class="diggnum" id="digg_count_3266366">10</span> </div> <div class="clear"></div> <div id="digg_tip_3266366" class="digg_tip"></div> </div> <div class="post_item_body"> <h3><a class="titlelnk" href="http://www.cnblogs.com/ola2010/p/3266366.html" target="_blank">python——常用功能之文本处理</a></h3> <p class="post_item_summary"> 前言在生活、工作中,python一直都是一个好帮手。在python的众多功能中,我觉得文本处理是最常用的。下面是平常使用中的一些总结。环境是python 3.30. 基础在python中,使用str对象来保存字符串。str对象的建立很简单,使用单引号或双引号或3个单引号即可。例如:s='nice' ... </p> <div class="post_item_foot"> <a href="http://www.cnblogs.com/ola2010/" class="lightblue">ola2010</a> 发布于 2013-08-18 21:27 <span class="article_comment"><a href="http://www.cnblogs.com/ola2010/p/3266366.html#commentform" title="2013-08-20 17:45" class="gray"> 评论(4)</a></span><span class="article_view"><a href="http://www.cnblogs.com/ola2010/p/3266366.html" class="gray">阅读(1640)</a></span></div> </div> <div class="clear"></div> </div> </body> </html>
代码:
from html.parser import HTMLParser import os,urllib.request,sys #一个简单的html解析器,主要用于看看Python对html的解析步骤 class TestParser(HTMLParser): def __init__(self,strict=False): HTMLParser.__init__(self,strict) self.current=0 def handle_starttag(self,tag,attrs): print(tag,':',attrs) def handle_data(self,data): print(self.current,'data:',data.strip()) self.current=self.current+1 if __name__=='__main__': parser=TestParser(strict=False) f=open(os.path.join(os.getcwd(),'test.txt'),encoding='utf-8') s=f.read() f.close() parser.feed(s)
通过小程序,确定好处理顺序之后,然后就可以将这些数据一步一步地抽取出来了。之前有一篇博客python——有限状态机写到怎么提取信息。
代码:
from html.parser import HTMLParser import os,urllib.request,sys #parser of content class ContentParser(HTMLParser): def __init__(self,strict=False): HTMLParser.__init__(self,strict) self.state=0 self.title='' self.author='' self.time='' self.comment='' self.view='' self.result=[] def handle_starttag(self,tag,attrs): if self.state==0: if tag=='a': for i in attrs: if i[0]=='class' and i[1]=='titlelnk': self.state=1 #title elif self.state==2: if tag=='div': for i in attrs: if i[0]=='class' and i[1]=='post_item_foot': self.state=3 elif self.state==3: if tag=='a': self.state=4 #author elif self.state==5: if tag=='span': for i in attrs: if i[0]=='class' and i[1]=='article_comment': self.state=6 elif self.state==6: if tag=='span': for i in attrs: if i[0]=='class' and i[1]=='article_view': self.state=7 def handle_data(self,data): if self.state==1: self.title=data.strip() self.state=2 elif self.state==4: self.author=data.strip() self.state=5 elif self.state==5: self.time=data.strip()[-16:] elif self.state==6: self.comment=data.strip()[3:-1] elif self.state==7: self.view=data.strip()[3:-1] self.result.append((self.title,self.author,self.time,self.comment,self.view)) self.state=0 def getContent(file_name): parser=ContentParser(strict=False) f=open(os.path.join(os.getcwd(),'data',file_name),encoding='utf-8') s=f.read() f.close() parser.feed(s) f=open(os.path.join(os.getcwd(),'result.txt'),'a') for i in parser.result: f.write('{0}\t{1}\t{2}\t{3}\t{4}\n'.format(i[0],i[1],i[2],i[3],i[4])) f.close() if __name__=='__main__': for i in os.listdir(os.path.join(os.getcwd(),'data')): print(i) getContent(i)
这样,就将结果提取出来了。
3. 分析这些数据
因为我们是以tab键分割这些数据的,所以可以导入到excel中:
经统计:
从2013-05-22 16:22到2013-08-20 19:57近3个月的时间里: 有1356个人发布4000篇博客到博客园首页,平均每天44.4篇,每人3篇; 其中,最高的一人发布了55篇; 所有的文章总共被查看4661643次,评论35210次,平均132次查看会有一次评论
抛砖引玉
1. 除了上述统计信息之外,是否可以找到一个星期中,那一天博客发表的最多?那一天最少?哪个人的评论最多?哪些主题关注度最大?
2. 互联网的数据有很多,只要肯动手,就能获取想要的信息。不仅仅是博客园的这些统计信息,也可以是其他网站的。
http://www.cnblogs.com/ola2010/