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

歩いたら休め

If the implementation is easy to explain, it may be a good idea.

【Python】不動産のドメイン知識を得るために、業界の方々が紹介しているリンク集を自動投稿するブログを作った

データ分析にはドメイン知識が必須です。

せっかく一生懸命分析しても、「あ、その結果ってそうなんだよ!でもありがたいけど、当たり前すぎて役にたたないなあ…」と言われ、がんばった成果が無駄になってしまうことも度々だとか。

売上がアップしても、その時期に自社のサービスが良くなったのではなく、実は業界全体が好景気だっただけだったということもあるそうです。これを意識しないと、間違った道にハマってしまうと思います。

「そのために最近住宅新報だとか全国賃貸住宅新聞」だとかのRSSを毎日チェックしてるんだよね」と不動産ポータルサイトでデータ分析している友人が言っていました。しかし、これらのサイトを見たところ、大小様々なニュースで溢れており、「何が重要で何が重要でないか判断できないなぁ…」と感じました。

というわけで、自動でいい感じのニュースを集めてくれるサイトを作ってみました。

fudosaninfo.hatenablog.com

基本的には、

  1. Twitter不動産業界のニュースをつぶやいている方々のURLを集める
  2. 多少フィルタリングをかける
  3. はてなブログAPIで投稿する

という簡単なロジックのプログラムを定期実行しているだけです。

はてなブログの投稿部分はこちら↓を参考に実装しました。

karaage.hatenadiary.jp

ただ、xmlをベタ打ちは見づらいなと感じたので、xmltodictというライブラリで辞書から変換するようにしています。

# -*- coding: utf-8 -*-                                                                                  

import requests
from datetime import datetime
import hashlib
from base64 import b64encode
from random import random
import xmltodict
from collections import OrderedDict

class postHatena:
    def __init__(self):
        self.username = 'takeshi0406'
        self.apikey = 'ナイショ♥'
        self.blogname = 'fudosaninfo.hatenablog.com'
        self.draft = 'no'

    def wsse(self, username, password):
        created = datetime.now().isoformat() + 'Z'
        nonce = hashlib.sha1(str(random())).digest()
        digest = hashlib.sha1(nonce + created + password).digest()
        return 'UsernameToken Username="{}", PasswordDigest="{}", Nonce="{}", Created="{}"'.format(userna


    def post_hatena(self, title, body):
        headers = {'X-WSSE': self.wsse(self.username, self.apikey)}
    
        url = 'http://blog.hatena.ne.jp/{}/{}/atom/entry'.format(self.username, self.blogname)
        data = self.make_data(title, body).encode('utf-8')
        r = requests.post(url, data=data, headers=headers)

    def make_data(self, title, body, category = u'不動産情報'):
        data = {
            u'entry': 
               OrderedDict(
                   [
                       (u'@xmlns', u'http://www.w3.org/2005/Atom'),
                       (u'@xmlns:app', u'http://www.w3.org/2007/app'),
                       (u'title', title),
                       (u'author', OrderedDict([(u'name', u'name')])),
                       (u'content', OrderedDict([(u'@type', u'text/plain'), ('#text', body)])),
                       (u'category', OrderedDict([(u'@term', category)])), 
                       (u'app:control', OrderedDict([(u'app:draft', u'"no"')]))
                   ]
            )
        }
        return xmltodict.unparse(data)

if __name__ == '__main__':
    client = postHatena()
    client.post_hatena(u'テスト投稿', u'ボディー')