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

ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

はてなブログの投稿予告tweetをするスクリプトを書いた

#はじめに はてなブログを書いているひとで、投稿予約を利用して同じ時間に投稿するひとも多いと思う。(根拠はない)

そうすると明日、明後日にどんな記事が投稿されるか予告のツイートをしたくなる。

今回ははてなブログAPItwitterAPIを利用し、Pythonで投稿するスクリプトを書いた。

github.com

このスクリプトをcronから蹴ってあげれば、好きな曜日、日時に投稿予告ツイートをすることができる。

TwitterAPIを利用するまで

開発者用ページにいって、4つのキーを取得する必要があります。

apps.twitter.com

twitter_tokens.pyに定義される4つのキーを入力してください。

ここでは詳細を省きます。電話番号認証が必須でした。

はてなAPIを使うためには

BASIC認証 でいけます。設定→詳細設定→AtomPubにルートエンドポイントとAPIキーが書かれています。

hatena_auth.pyに記入してください。これではてなブログへの投稿や記事の取得ができます。

hatena_notice.py

メインのプログラムです。83step。もっと短くできたかもしれませんね。軽く解説します。

def get_drafts():
    drafts = []
    global URL
    
    for i in range(REPEAT):
        res = session.get(URL,auth=(USER,APIKEY))
        soup = BeautifulSoup(res.text, "html.parser")
        URL = soup.find("link", rel="next").get('href')

        article = soup.find("feed").find_all("entry")
        for art in article:
            isdraft = art.find("app:control").find("app:draft").text
            if isdraft == 'yes':
                title = art.find("title").text
                updated = art.find("updated").text
                draft=[title,updated]
                drafts.append(draft)
    return drafts

記事の中からdraft状態のものを取得します。実際にはてなAPIを投げている部分もここです。REPEAT変数で指定された回数、nextページに繰り返し取得します。だいたい10ページもとれば、よほどストックがあるひとじゃない限り大丈夫だと思います。

取得したXMLをbeautiful soupを使って欲しいところをとっています。下書きかどうかをisdraftで判定して、下書きのもののtitleとupdatedを取得して返却する関数です。

def get_reserve(drafts):
    reserve = []
    now = datetime.datetime.now()

    for draft in drafts:
        date = datetime.datetime.strptime(draft[1],"%Y-%m-%dT%H:%M:%S+09:00")
        if now < date:
            #convert string to datetime
            draft[1] = date
            reserve.append(draft)
    return reserve

次に下書きの記事の中から、更新予約をしているもの、すなわちupdateが今より未来の日付のものを抽出します。datetimeとstrignの変換をここで学びました。ここではstringのtitleと、日付はdatetimeで返しています。

def tweet_extract(reserve):
    text = "update notice:"
    for art in reserve:
        date = art[1].strftime('%m/%d')
        
        if len(text) + len(art[0]) > 140:
            break
        text += "%s:%s" % (date,art[0])
    return text

最後につぶやくための文字列を作成しています。140文字以上になってはいけないので、足しあわせた結果が140文字を超える場合は加算せずloopから抜けます。

def tweet(text):
    URL = 'https://api.twitter.com/1.1/statuses/update.json'

    payload = {'status': text}
    req = twitter.post(URL, params = payload)

    return req.status_code

ここは単にツイートしているところですね。楽です。

tweepyというライブラリもあるようですが、今回はOAuth認証部分だけライブラリを用いて、requestモジュールで投稿しています。

おわりに

Pythonを最近は意識的に触っています。だいぶ慣れてきました。テストコードはモックの作り方がわかってないのではてなAPIを実行する部分やツイートする部分がかけていません。

一応誰でも使えるよう汎用的にして(個別の設定値は外出しにして)必要なライブラリを書いてgithubに公開できたので以前より進歩です!(以前はシェルとrubyのゴミみたいなスクリプト書いてた)

Beatifulsoupやtwitter-apiははやく使いこなせるようになってスクレイピングで遊びたいな。