RSSフィードから単一品詞の単語別出現数を取得してみた.
今回はOreilly集合知プログラミングの第3章を参考に
単一品詞の単語別出現数を取得するPythonコードを作成してみました.
- 作者: Toby Segaran,當山仁健,鴨澤眞夫
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/07/25
- メディア: 大型本
- 購入: 91人 クリック: 2,220回
- この商品を含むブログ (277件) を見る
RSSフィードから,各記事のタイトル,リンク,エントリ等を取り出すのには
Universal Feed Parserというpythonのモジュールを用います.
また,形態素解析には前回の記事で利用したMeCabを使います.
作成コード
日本語をcsvファイルへ出力する部分はココを参考にさせてもらいました.
また,extractKeyword関数やcsvモジュールについてはそれぞれ過去の記事(クリックすれば飛ぶ)で扱っています.
#coding:utf-8 import re import csv import MeCab import feedparser from extractKeyword import extractKeyword # ////////////////////// # ----- set URLs ----- # ////////////////////// URLs = ['http://news.livedoor.com/topics/rss/dom.xml', 'http://dailynews.yahoo.co.jp/fc/rss.xml', 'http://news.google.com/news?hl=ja&ned=us&ie=UTF-8&oe=UTF-8&output=atom&topic=h&hl=ja', 'http://sankei.jp.msn.com/rss/news/points.xml'] # ///////////////////////////////// # ----- category selection ----- # ///////////////////////////////// class_num = 0 word_classes = [u'名詞',u'動詞',u'形容詞',u'副詞',u'助詞',u'助動詞'] word_class = word_classes[class_num] # /////////////////////////////// # ----- defined functions ----- # /////////////////////////////// def getwordcounts(url): """RSSフィードのタイトルと、単語の頻度のディクショナリを返す""" # フィードをパースする d = feedparser.parse(url) wc={} # すべてのエントリをループする for e in d.entries:# RSSの種類によって,記事に相当する部分が異なることに対応する if 'summary' in e: summary = e.summary elif 'description' in e: summary = e.description else: summary = e.link # 単語のリストを取り出す words = getwords(e.title+' '+summary) # extractKeywordを用いるため,単語を連結してテキスト化 txt = '' for i in range(len(words)): txt += words[i] words_sub = extractKeyword(txt,word_class) for word in words_sub: wc.setdefault(word,0)# dict型のkeyにwordがなければ,value=0として新設 wc[word] += 1 return d.feed.title,wc def getwords(html): """すべてのHTMLタグを取り除き,単語リストを返す""" txt = re.compile(r'<[^>]+>').sub('',html)# htmlから'<[^>]+>'を''に置き換える tagger = MeCab.Tagger('-Owakati') return tagger.parse(str(txt)).split(' ') def main(): apcount = {} wordcounts = {} feedlist = [line for line in URLs] for feedurl in feedlist: wc = {} try: title,wc_ini = getwordcounts(feedurl) for w,bc in wc_ini.items(): wc.setdefault(w.encode('sjis'),bc)# csvで日本語を表示させるため,Shift_JIS化 wordcounts[title] = wc for word,count in wc.items(): apcount.setdefault(word,0) if count>1: apcount[word]+=1# それぞれの単語が出現するフィードの数を数える except: print 'Failed to parse feed %s' % feedurl# urlが認識できなければエラー表示 # でたらめな単語が存在するフィードがあることや一般的な単語の除外を考慮し,単語の出現率に敷居値を設定する wordlist = [] for w,bc in apcount.items(): frac = float(bc)/len(feedlist) if frac>0.1 and frac<0.5: wordlist.append(w) # csvへの書き込み用リストを生成 header = ['Feed_name']+wordlist rows = [] for blog,wc in wordcounts.items(): row = [blog.encode('sjis')] for word in wordlist: if word in wc: row.append(wc[word]) else: row.append('0') rows.append(row) # csvへ書き込み csv_writer = csv.writer(open('rss_data.csv','w'),lineterminator='\n') csv_writer.writerow(header) csv_writer.writerows(rows) if __name__ == "__main__": main()
- -
[注] csvへの書き込みようリストを生成する部分で
# wordlistのkeyはShift-JIS化済みで,wordcountのはutf-8形式として... for blog,wc in wordcounts.items(): for word in wordlist: if word in wc: row.append(wc[word].encode('sjis')) else: row.append('0')
だと'wc'がの日本語の場合,条件分岐'if word in wc:'において,その'else:'部分しか実行されなくなる.