とのことで触ってみた
はてなのAPIを扱うのは初めて。
Python以外の言語のサンプルを見るとAtomを扱えるライブラリがあれば簡単に書けるみたいですが、Pythonのそういったライブラリに詳しくないので処理をそのまま書いときます
WSSE認証
以下のWSSEという方法で認証するみたいです
はてなのサンプルにはPythonがなかったので、以下の記事を参考にしました
- AtomPub(Atom Publishing Protocol)
- PythonでAtomクライアント - Moderation is a fatal thing. Nothing succeeds like excess.
以下のコードのようにユーザー名とパスワード(とランダムな文字列)を与えれば認証用の文字列が作れるみたいです
この文字列を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とかよりも使いやすいらしいです
- シンプルで覚えやすい仕様,パワフルなPythonのWebアクセスモジュール request | TRIVIAL TECHNOLOGIES @ats のイクメン日記
- python向けHTTP関連モジュールのrequestsが便利すぎる - yattの日記
- Requests: 人間のためのHTTP — requests-docs-ja 1.0.4 documentation
# -*- 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'にAtomのXMLを投稿すればよいみたいです
# -*- 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)