読者です 読者をやめる 読者になる 読者になる

COBOL技術者の憂鬱

COBOLプログラマは不在にしています

「2chまとめhotentry」というWebサービスを作ります

実は3月から職場が異動になり、その影響で少しバタバタしていたのですが、ようやく落ち着いてきたので連載プログラミングの方も少しずつ再開していきたいと思います。


今回から第二弾の製作に入りますが、ネタを色々検討した結果、2ちゃんねるのまとめサイトを集約して表示するサイトを作ることにしました。
いわゆる「まとめのまとめ」というやつですが、既にこういう感じのサイトがあったりするので、同じことをやってもあまり意味がありませんよね。
そこで、はてブのブクマ数を基準にして各エントリの注目度を算出し、今一番注目されているエントリを順番に表示できるようにしておけば、閲覧するユーザーにとって時間の節約につながるのではないでしょうか。私のように、「まとめのまとめ」をじっくり眺めている時間すらないという多忙なビジネスマンの方に捧げることにしましょう。


というわけで、これから作っていく機能は以下のような感じになります。


  • はてブの新着エントリーから2ちゃんねるのまとめサイトエントリーのみを抽出し、データストアに登録するプログラムを作成し、cronで回す。
  • 上記プログラムに対して、各エントリーの注目度を算出して付与する機能を追加する。
  • 上記データストアから、注目度順にエントリーを表示するプログラムを作成する。

実は、上記リストの内、2番目までは既にだいたい出来上がっています。
どういうことができたらいいか頭の中で考えている内に、実際に作って動かしてみた方が絶対わかりやすいと思っていろいろ手を動かしている間に、自然と出来上がってしまいました。
昨日から実際に、本番環境で稼働させているので、あとはしばらく結果を様子見してみて、あちこち調整を加えていこうと思っています。
こういう集合知的な要素を持ったプログラムは、試験的に稼働させてみないとどういう動きをするのか全く予想がつかないので、こういうやり方をするのがベストなのではないかなと最近思うようになりましたね。


現在、以下のプログラムを20分に1回のタイミングで稼働させています。


【get_entry.py】

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from google.appengine.api import urlfetch
import re
import datetime

import datastores

query1 = datastores.Sites.gql('ORDER BY check_time ASC')
site = query1.get()

if site:
  entrylist_url = 'http://b.hatena.ne.jp/entrylist?url=' + site.url
  result = urlfetch.fetch(entrylist_url)
  if result.status_code == 200:
    query2 = datastores.Entries.gql('WHERE parent_site = :parent_site AND score > :score',parent_site=site,score=0)
    for scorefilled_entry in query2:
      scorefilled_entry.score = 0
      scorefilled_entry.put()
    pattern = re.compile(r'''<li class="users"> <strong><a href="/entry/(.*?)" title="(.*?)">(.*?) users</a></strong></li>
        <li class="timestamp">(.*?)</li>(.*?)
        <cite title="(.*?)"><a href="(.*?)"> 続きを読む</a></cite>''',re.S)
    entry_lists = pattern.findall(result.content)
    for entry_list in entry_lists:
      query3 = datastores.Entries.gql('WHERE url = :url',url=entry_list[6])
      entry = query3.get()
      if entry:
        entry.increase3 = entry.increase2
        entry.increase2 = entry.increase1
        entry.increase1 = int(entry_list[2]) - entry.count
        entry.count = int(entry_list[2])
      else:
        entry = datastores.Entries()
        entry.url = entry_list[6]
        entry.title = unicode(entry_list[5],'utf-8')
        entry.date = entry_list[3]
        entry.count = int(entry_list[2])
        entry.increase3 = 0
        entry.increase2 = 0
        entry.increase1 = int(entry_list[2])
        entry.parent_site = site
      entry.score = entry.increase1 + int(entry.increase2 * 0.6) + int(entry.increase3 * 0.3)
      entry.put()
    site.check_time = datetime.datetime.today()
    site.put()


この状態で2〜3日稼働させてみて、データストアの状態を眺めつつフロント部分を作っていきたいと思います。