• python——博客园首页信息提取与分析


    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是怎么解析这些数据的:

    数据:

    复制代码
     View Code
    复制代码

    代码:

    复制代码
    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}	{1}	{2}	{3}	{4}
    '.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:222013-08-20 19:573个月的时间里:
    有1356个人发布4000篇博客到博客园首页,平均每天44.4篇,每人3篇;
    其中,最高的一人发布了55篇;
    所有的文章总共被查看4661643次,评论35210次,平均132次查看会有一次评论
    复制代码

    抛砖引玉

    1. 除了上述统计信息之外,是否可以找到一个星期中,那一天博客发表的最多?那一天最少?哪个人的评论最多?哪些主题关注度最大?

    2. 互联网的数据有很多,只要肯动手,就能获取想要的信息。不仅仅是博客园的这些统计信息,也可以是其他网站的。

     

    TAG: emacs, python, cedet, semantic, ctags 
    DATE: 2013-08-20

    我用Emacs 24写python程序。 发现屏幕不时有些闪动,MiniBuffer有消息一闪而过。 我打开 *Messages* buffer,发现有许多这样的消息:

    CTAGS/movie-scheduling.py...
    Can't guess python-indent-offset, using defaults: 4
    Mark set [7 times]
    CTAGS/movie-scheduling.py...
    Can't guess python-indent-offset, using defaults: 4
    Mark set [7 times]
    CTAGS/movie-scheduling.py...
    Can't guess python-indent-offset, using defaults: 4
    Mark set [7 times]
    ... ...
    

    每当我修改python程序,就会不停出现类似上面的消息。消息增加得很快,几乎两秒增 加一次。有时会占用许多CPU,导致输入程序有延迟。

    不知道这是 python-mode 的问题,还是 semantic 在分析文件。

    如果是 semantic 在分析文件, 在我写 c/c++/java 程序时, semantic的活动又没有这么频繁。

    通过以下的分析,发现不是 python-mode 的问题,也不是semantic的问题,具体来说 是semantic启用ctags辅助产生的问题。

    1. 不启用cedet,编辑python程序,不会出现上面说的问题,说明不是python模式的问 题。
    2. 启用cedet,编辑python程序,问题又出现。每次一改动python程序,就会出现问题 中描述的信息。但是semantic分析文件,怎么会调用ctags呢?

      我发现我的.emacs中,cedet的设置有这样一句:

      (semantic-load-enable-all-exuberent-ctags-support)
      

      应该就是它了,注释掉这一句,重启emacs,再编辑python程序,不再出现上面的问题了。

    3. 要想保留ctags对semantic的支持,也可以保留上面的配置,再加一句也可以解决问题。

      (global-semantic-idle-scheduler-mode nil)
      

      不让semantic利用空闲时间分析文件,它也就不会频繁地调用ctags分析python文件 了。 这样做的坏处就是,当你要访问某个tag时,semantic可能要临时分析,花的 时间较长。 不过可以忍受

     
     
    标签: Emacspythoncedetsemanticctags
    http://www.cnblogs.com/ola2010/
     
  • 相关阅读:
    4、2 核心组件
    promise
    Content-Type
    $routeProvider
    广告
    $apply() $digest()
    异常
    switch
    autoprefixer
    $resource
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3271550.html
Copyright © 2020-2023  润新知