对博客订阅源URL中的单词进行计数 (仅限英文博客,中文订阅源不支持 )

工具:python,第三方包universal feed parser(用以对订阅源里的URL分析)

目的:分析URL,对URL里的单词全部进行统计

结果:输出一个文件,存的是一个矩阵,每一列对应一个单词,每一个对应一个博客

 

问题:哪里找URL?

步骤1:收集订阅源,即收集URL:   网上已有的feedlist.txt,里面装的是URL列表:

http://feeds.feedburner.com/TechCrunch
http://www.techdirt.com/techdirt_rss.xml
http://www.thesuperficial.com/index.xml
http://www.tmz.com/rss.xml
http://www.tuaw.com/rss.xml

 

这是部分URL列表

问题2:找到URL后,目的是什么?

   答:最终目的是找出所有单词,和词频

    所以需要:1.获取每条url里的单词及词频。 (说明要用到字典,这里用wc 存储 单词和词频)

            2.获取单词之前先要分词,所以先要对URL进行分词(用正则表达式分出单词)

            3.分词之前,先要解释URL (用第三方库feedparser 解析URL)

步骤2: 解析url,在分词,存储单词+词频

# coding=gb2312  
import feedparser
import  types
import re

 def getwordcounts(url):
    #解析订阅源
    d =feedparser.parse(url)    
    wc = {}         #定义wordcount字典 。key是单词,value是单词数
   
    #循环遍历所有文章条目,文章条目放到d.entries的list里
    for e in d.entries :        #d.entries 是一个list类型。可以用help(d.entries)查看
        if 'summary' in e :     #这里只处理英文博客,不处理中文博客。
            summary = e.summary     #文章的摘要
        else:
            summary = e.description     #文章的描述性标签
     
        #提取一个单词列表
        words = getwords(e.title +"  " +summary)  #参数为 标题和 一组文章的摘要     
        for word in words:
            wc.setdefault(word,0)   #初始化源代码,如果键在字典中,返回这个键所对应的值。如果键不在字典中,向字典 中插入这个键
            wc[word]+=1             #最终wc存了所有文章的词和词频
     return  d.feed.title, wc            #d.feed.title返回的是url的主要网址名,e.g www.baidu.com,title是baidu.

def getwords(html): '''进行分词。用正则表达式分词 这里只进行英文分词。 ''' #去除所有html标记..sub是什么函数?? txt = re.compile(r'<[^>]+>').sub('',html) #“[]" 表示这是字符类,+表示1个或多个 #利用所有非字母 words = re.compile(r'[^A-Z^a-z]+').split(txt) #^表示非。”[]“ 表示这是字符类 #转化成小写形式 return [word.lower() for word in words if word !='']

 

其中d.entries内容是: 

title是:Weekend giveaway: Pad and Quill Aria iPad cases -- and discounts
文章的单词: weekend giveaway pad and quill aria ipad cases and discounts mr and mrs pq proprietors of pad and quill llc in lovely minneapolis minnesota are apparently trying to keep themselves sane in this year s wacky spring weather it was crazy in colorado yesterday too they re warming things
title是:Minecraft Pocket Edition hits 10 million downloads
文章的单词: minecraft pocket edition hits million downloads mojang has announced that the pocket edition of its extremely popular sandbox game minecraft has also reached million downloads a feat made even more impressive by the fact that the app is being sold for a premium price of the original pc version of minecraft hit million sales back on april but .....
.......
........

其中 每次 e 就取上面一段 即如 : title是:Minecraft Pocket Edition hits
10 million downloads 文章的单词: minecraft pocket 。。。。

 

 

 


 

简单流程:

 给出URLlist列表feedlist

 对feedlist逐条url取出:

    获得该条url的单词和词频放在字典wordcounts的value中

最终wordcounts存储了{博客名,所有url的单词+词频}

 

最终结果即可输出:

输出矩阵的列: wordcounts的所有单词

输出矩阵的行: 输出 每条url博客名,\t 输出 wordcount中相应单词的词频

(其中每条url,代表一行)

如下图,feedlist.txt一共只有2条url,所以最终结果是 两行n列:

结果说明:

TUAW - The Unofficial Apple Weblog

Techdirt. 是博客名。

limited kickstart saves yellow......是单词

 

所以简化版代码如下:

wordcounts = {}

#读url列表文件
feedlist = [line for line in file('urllist1.txt')]   
print 'feedlist的长度是',len(feedlist) 
for feedurl in feedlist:                #一条URL就是一条博客,就是矩阵的一行。
    try:
        title,wc = getwordcounts(feedurl) #一条URL就只有一条title名称
        wordcounts[title] = wc          #wordcounts字典里套着字典,key是博客名称 title,value是”词和词频“的字典
    except:
        print '此URL不能分析 %s' % feedurl


'''建立单词列表
 '''
wordlist = []
for title,wc in wordcounts.items():
    for word,count in wc.items():
        wordlist.append(word)
print wordlist


'''
输出文件中,一条url就是矩阵的一行
'''
out = file("resultfinaltest.txt",'w')
out.write('Blog')
for word in wordlist:    
    out.write('\t%s' %word)
out.write('\n')

for blogtitle,wc in wordcounts.items():   #一条URL就用一条blogtitle
    out.write(blogtitle)
    for word in wordlist:
        if word in wc:          #表示字典wc有key是word.   
            out.write('\t%d' % wc[word])
        else :
            out.write('\t0')
    out.write('\n')

 

然而,这样的问题是,矩阵的单词很多,而且很多单词如the/a 这些高频停用词 无需计算,一些在所有博客中只出现一次的也 无需放进矩阵了,

所以还要对上面的矩阵进行 单词 缩减:

 

所以代码增为: 

对比上面:

blogcountforeveryword ={}  #出现这些单词的博客数目
wordcounts = {}

#读url列表文件
feedlist = [line for line in file('urllist1.txt')]   
print 'feedlist的长度是',len(feedlist) 
for feedurl in feedlist:                #一条URL就是一条博客,就是矩阵的一行。
    try:
        title,wc = getwordcounts(feedurl) #一条URL就只有一条title名称
        wordcounts[title] = wc          #wordcounts字典里套着字典,key是博客名称 title,value是”词和词频“的字典
          
        #blogcountforeveryword是存出现单词的博客数目
        for word ,count in wc.items(): 
            blogcountforeveryword.setdefault(word,0)  #如果apcount已经存了word这个key,则返回该值,不再重设为0
#             if count>=2:          #一条url里的文章单词,如果单词词频大于等于2,才能算占用一条博客,不然词频<2,不算占用一条博客。这是对单词的筛选。这句话可删。。
            blogcountforeveryword[word]+=1            #因为wc是字典,word在wc作为key是唯一的,所以这句话每个url只访问一次。
         
    except:
        print '此URL不能分析 %s' % feedurl



    
'''建立单词列表
对于某些单词只出现在个别博客滤过,对于the,a这些高频停用词出现在所有博客的滤过,
总之,消除过多和鲜见的单词
'''
wordlist = []
# 对比上面的简化版,其实现在版本就是多了下面的过滤部分设置
#for title,wc in wordcounts.items():
# for word,count in wc.items(): # wordlist.append(word) for word,blogcount in blogcountforeveryword.items(): frac = float(blogcount)/len(feedlist) #len(feedlist)里面有多少条url,长度就是多少 if frac >0.1 and frac <0.8: #frac>0.1 可以消除那些blogcount==0的单词 wordlist.append(word) ''' 输出文件中,一条url就是矩阵的一行 ''' out = file("resultfinaltestmore.txt",'w') out.write('Blog') for word in wordlist: out.write('\t%s' %word) out.write('\n') for blogtitle,wc in wordcounts.items(): #一条URL就用一条blogtitle out.write(blogtitle) for word in wordlist: if word in wc: #表示字典wc有key是word. out.write('\t%d' % wc[word]) else : out.write('\t0') out.write('\n')
posted @ 2013-05-04 21:49  无脚的鸟  阅读(575)  评论(0编辑  收藏  举报