唯物是真 @Scaled_Wurm

プログラミング(主にPython2.7)とか機械学習とか

はてなブログのAPIが公開されたらしいので簡単に触ってみた(Python)

とのことで触ってみた
はてなのAPIを扱うのは初めて。

Python以外の言語のサンプルを見るとAtomを扱えるライブラリがあれば簡単に書けるみたいですが、Pythonのそういったライブラリに詳しくないので処理をそのまま書いときます

WSSE認証

以下のWSSEという方法で認証するみたいです

はてなのサンプルにはPythonがなかったので、以下の記事を参考にしました

以下のコードのようにユーザー名とパスワード(とランダムな文字列)を与えれば認証用の文字列が作れるみたいです
この文字列をHTTPのX-WSSEヘッダに指定すればAPIが使えます

今回使うAPIではユーザー名は、はてなのID、パスワードは詳細設定のページに書かれているAPIキーを使います

import datetime
import random
import hashlib
import base64

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

API

APIの詳細は以下にあります

主に使いそうな機能は「エントリ一覧の取得」「エントリの取得」「エントリの新規投稿」あたりだと思います

エントリ一覧の取得

'http://blog.hatena.ne.jp/ユーザー名/ブログのアドレス/atom/entry'にGETリクエストをすればエントリの一覧が取得できます
注意点としては7件ずつしか記事を取得できないことです(ページを指定できるらしいですが

以下ソースコード
requestsというライブラリを使っているので注意
標準ではないですがurllib2とかよりも使いやすいらしいです

# -*- coding: utf-8 -*-
import datetime
import random
import hashlib
import base64
import requests

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


username = 'ユーザー名'
password = 'APIキー'
blogname = 'ブログのアドレス'
headers = {'X-WSSE': wsse(username, password)}

url = 'http://blog.hatena.ne.jp/{}/{}/atom/entry'.format(username, blogname)

r = requests.get(url, headers=headers)
print r.text.encode('utf-8')

エントリの取得

エントリ一覧では'http://blog.hatena.ne.jp/ユーザー名/ブログのアドレス/atom/entry'をGETしていました。
個々のエントリがほしい時には'http://blog.hatena.ne.jp/ユーザー名/ブログのアドレス/atom/entry/エントリID'をGETすればよいです。

エントリの投稿

'http://blog.hatena.ne.jp/ユーザー名/ブログのアドレス/atom/entry'にAtomXMLを投稿すればよいみたいです

# -*- coding: utf-8 -*-
import datetime
import random
import hashlib
import base64
import requests

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


username = 'ユーザー名'
password = 'APIキー'
blogname = 'ブログのアドレス'
headers = {'X-WSSE': wsse(username, password)}

url = 'http://blog.hatena.ne.jp/{}/{}/atom/entry'.format(username, blogname)

data = """<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
       xmlns:app="http://www.w3.org/2007/app">
  <title>title</title>
  <author><name>name</name></author>
  <content type="text/plain">
    content
  </content>
  <updated>2013-09-05T00:00:00</updated>
  <app:control>
    <app:draft>yes</app:draft>
  </app:control>
</entry>
"""

r = requests.post(url, data=data, headers=headers)