ゴミ箱の中のメモ帳

まだ見ぬ息子たちへ綴る手記

はてなブログ AtomPub コレクションXML フォーマット仕様

前回の記事に書いたように、はてなブログのAtomPubを試してみると「はてなブログAtomPub」に書かれているコレクションのレスポンスとは少し変わっているかも知れないと思ったので私なりに調べた結果を書く。結果から言うと、コレクションからは7件ではなく10件のブログエントリが取得でき、さらにはnextリレーションタグは次のページがなければ挿入されないなど、書かれていない仕様がいくつかあった。

ただしココに書かれていることも今現在に私が調べた結果であり、今この記事を読まれている瞬間には仕様が変わっている可能性もあるし、さらには条件によっては違う結果になるかも知れないという点に置いては注意して下さい。ブログ記事に書くという都合上常に最新のバージョンを追いかけるわけには行かないので、そのうち静的なWebページにまとめようかと思う。

「へんな会社」のつくり方 (NT2X)

「へんな会社」のつくり方 (NT2X)


まず、前の記事の通りWSSE認証で取得できるコレクションは以下のようになる。生データなのでかなり長いがご愛嬌。

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:app="http://www.w3.org/2007/app">

  <link rel="first" href="http://blog.hatena.ne.jp/mon0/mon0.hatenablog.jp/atom/entry" />


  <link rel="next" href="http://blog.hatena.ne.jp/mon0/mon0.hatenablog.jp/atom/entry?page=1392811641" />


  <title>起業と読書と人生と</title>

  <subtitle>起業への活動と、日々の読書と、人生について書かれた紙片</subtitle>

  <link rel="alternate" href="http://blog.mon0.jp/"/>
  <updated>2014-02-26T10:52:17+09:00</updated>
  <author>
    <name>mon0</name>
  </author>
  <generator uri="http://blog.hatena.ne.jp/" version="ad4baa17ce5956c437352b80fe3669ae">Hatena::Blog</generator>
  <id>hatenablog://blog/11696248318755645593</id>


  <entry>
    <id>tag:blog.hatena.ne.jp,2013:blog-mon0-11696248318755645593-12921228815719030568</id>
    <link rel="edit" href="http://blog.hatena.ne.jp/mon0/mon0.hatenablog.jp/atom/entry/12921228815719030568"/>
    <link rel="alternate" type="text/html" href="http://blog.mon0.jp/entry/2014/02/26/105217"/>
    <author><name>mon0</name></author>
    <title>はてなブログ AtomPub APIのPython WSSEサンプルコード</title>
    <updated>2014-02-26T10:52:17+09:00</updated>
    <published>2014-02-26T10:52:17+09:00</published>
    <app:edited>2014-02-26T10:52:17+09:00</app:edited>
    <summary type="text">はてなブログにはAtom Publishing Protocol(AtomPub)が実装されており、そのAPIを利用することではてなブログの記事一覧を取得することや記事を投稿、編集、削除することが出来る。はてなブログAtomPubにAPI仕様の簡単な説明といくつかの言語のサンプル…</summary>
    <content type="text/x-hatena-syntax">はてなブログにはAtom Publishing Protocol(AtomPub)が実装されており、そのAPIを利用することではてなブログの記事一覧を取得することや記事を投稿、編集、削除することが出来る。

    [http://developer.hatena.ne.jp/ja/documents/blog/apis/atom:title=はてなブログAtomPub]にAPI仕様の簡単な説明といくつかの言語のサンプルコードが掲載されている。が、PerlとRubyはサンプルコードとして理解できるものの、3つめのサンプル言語がScalaというのが納得行かない。はてなにPython嫌われてるよ。嫌われてるよ。

    ということで、簡単なWSSE認証のPythonのサンプルを書いておく。

    [asin:4873113938:detail]

    =====

    いきなりだがサンプルコード。

    &gt;|python|
    #!/usr/bin/python

    import datetime
    import random
    import hashlib
    import base64
    import urllib2

    userid = &quot;[UserID]&quot;
    apikey = &quot;[AtomPub API Key]&quot;
    blogid = &quot;[BlogID]&quot;
    apiurl = &quot;http://blog.hatena.ne.jp/%s/%s/atom/entry&quot; % ( userid, blogid)



    def make_wsse( userid, apikey):
    created = datetime.datetime.now().isoformat() + &quot;Z&quot;
    nonce = hashlib.sha1( str( random.random())).digest()
    digest = hashlib.sha1( nonce + created + apikey).digest()

    return &#39;UsernameToken Username=&quot;%s&quot;, PasswordDigest=&quot;%s&quot;, Nonce=&quot;%s&quot;, Created=&quot;%s&quot;&#39; % ( userid, base64.b64encode( digest), base64.b64encode( nonce), created)


    headers = { &quot;X-WSSE&quot;: make_wsse( userid, apikey)}
    request = urllib2.Request( apiurl, headers=headers)
    response = urllib2.urlopen( request)
    print response.read()
    ||&lt;


    |userid|ログイン等に使うユーザ名|
    |apikey|ブログの詳細設定にきさいされているAPIキー|
    |blogid|mon0.hatebalog.jp等のURL。ブログの基本設定にブログURLとして記載|

    これを変更すればそのまま使える。実行すると直近の記事7件(10件?)に関連するAtomが出力される。


    はてなブログのAtomPub APIはBasic認証、WSSE認証、OAuthに対応している様子。Basic認証は試していないが最も単純に認証を行えるかと思う。だがBasic認証はセキュリティ的にあんまりよくなさそうなのでWSSE認証を選択した。世間的にはOAuthがベターかと思うが、アプリケーションの登録が必要などサンプルコード以外の説明も必要になるためWSSE認証とした。

    また、先のAPI説明ページではAtomの解析までおこなっているようだが、このサンプルでは生のXMLを取得するまでとする。このXMLはAPI説明ページの内容とは少々異なるため、ドキュメントの内容から少々更新されているのかも知れない。また、ドキュメントにはXMLのフォーマットまで解説されていないので近日中にXMLのフォーマットを確認し記事にしようかと思う。

    コードを変更する際は誤ってDELETE命令を出さないように注意。DELETEするともちろん復元することができない。


    はてなブログにはエクスポート機能が提供されていないが、このAtomPub APIを用いることで全記事を取得できるようなのでエクスポート機能を実装できるかと思う。これも近日中に作成して記事にしようかと思う。

    [asin:4774142298:detail]
    [asin:477415539X:detail]
    [asin:4774142042:detail]
    [asin:0470087889:detail]
    </content>
    <hatena:formatted-content type="text/html" xmlns:hatena="http://www.hatena.ne.jp/info/xmlns#">&lt;p&gt;&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0&quot;&gt;はてなブログ&lt;/a&gt;には&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Atom&quot;&gt;Atom&lt;/a&gt; Publishing Protocol(AtomPub)が実装されており、その&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/API&quot;&gt;API&lt;/a&gt;を利用することで&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0&quot;&gt;はてなブログ&lt;/a&gt;の記事一覧を取得することや記事を投稿、編集、削除することが出来る。&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://developer.hatena.ne.jp/ja/documents/blog/apis/atom&quot;&gt;&amp;#x306F;&amp;#x3066;&amp;#x306A;&amp;#x30D6;&amp;#x30ED;&amp;#x30B0;AtomPub&lt;/a&gt;&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/API&quot;&gt;API&lt;/a&gt;仕様の簡単な説明といくつかの言語のサンプルコードが掲載されている。が、&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Perl&quot;&gt;Perl&lt;/a&gt;&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Ruby&quot;&gt;Ruby&lt;/a&gt;はサンプルコードとして理解できるものの、3つめのサンプル言語が&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Scala&quot;&gt;Scala&lt;/a&gt;というのが納得行かない。&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA&quot;&gt;はてな&lt;/a&gt;&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Python&quot;&gt;Python&lt;/a&gt;嫌われてるよ。嫌われてるよ。&lt;/p&gt;&lt;p&gt;ということで、簡単なWSSE認証の&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Python&quot;&gt;Python&lt;/a&gt;のサンプルを書いておく。&lt;/p&gt;&lt;p&gt;&lt;div class=&quot;hatena-asin-detail&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/4873113938/mon0-22/&quot;&gt;&lt;img src=&quot;http://ecx.images-amazon.com/images/I/41vF73wVaAL._SL160_.jpg&quot; class=&quot;hatena-asin-detail-image&quot; alt=&quot;初めてのPython 第3版&quot; title=&quot;初めてのPython 第3版&quot;&gt;&lt;/a&gt;&lt;div class=&quot;hatena-asin-detail-info&quot;&gt;&lt;p class=&quot;hatena-asin-detail-title&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/4873113938/mon0-22/&quot;&gt;初めてのPython 第3版&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;作者:&lt;/span&gt; Mark Lutz,夏目大&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;出版社/メーカー:&lt;/span&gt; &lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%A5%AA%A5%E9%A5%A4%A5%EA%A1%BC%A5%B8%A5%E3%A5%D1%A5%F3&quot;&gt;オライリージャパン&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;発売日:&lt;/span&gt; 2009/02/26&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;メディア:&lt;/span&gt; 大型本&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;購入&lt;/span&gt;: 12人 &lt;span class=&quot;hatena-asin-detail-label&quot;&gt;クリック&lt;/span&gt;: 423回&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://d.hatena.ne.jp/asin/4873113938/mon0-22&quot; target=&quot;_blank&quot;&gt;この商品を含むブログ (127件) を見る&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class=&quot;hatena-asin-detail-foot&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;
    &lt;p&gt;いきなりだがサンプルコード。&lt;/p&gt;
    &lt;pre class=&quot;code lang-python&quot; data-lang=&quot;python&quot; data-unlink&gt;&lt;span class=&quot;synComment&quot;&gt;#!/usr/bin/python&lt;/span&gt;

    &lt;span class=&quot;synPreProc&quot;&gt;import&lt;/span&gt; datetime
    &lt;span class=&quot;synPreProc&quot;&gt;import&lt;/span&gt; random
    &lt;span class=&quot;synPreProc&quot;&gt;import&lt;/span&gt; hashlib
    &lt;span class=&quot;synPreProc&quot;&gt;import&lt;/span&gt; base64
    &lt;span class=&quot;synPreProc&quot;&gt;import&lt;/span&gt; urllib2

    userid = &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;[UserID]&amp;quot;&lt;/span&gt;
    apikey = &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;[AtomPub API Key]&amp;quot;&lt;/span&gt;
    blogid = &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;[BlogID]&amp;quot;&lt;/span&gt;
    apiurl = &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;http://blog.hatena.ne.jp/%s/%s/atom/entry&amp;quot;&lt;/span&gt; % ( userid, blogid)



    &lt;span class=&quot;synStatement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;synIdentifier&quot;&gt;make_wsse&lt;/span&gt;( userid, apikey):
    created = datetime.datetime.now().isoformat() + &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;Z&amp;quot;&lt;/span&gt;
    nonce = hashlib.sha1( &lt;span class=&quot;synIdentifier&quot;&gt;str&lt;/span&gt;( random.random())).digest()
    digest = hashlib.sha1( nonce + created + apikey).digest()

    &lt;span class=&quot;synStatement&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;synConstant&quot;&gt;&#39;UsernameToken Username=&amp;quot;%s&amp;quot;, PasswordDigest=&amp;quot;%s&amp;quot;, Nonce=&amp;quot;%s&amp;quot;, Created=&amp;quot;%s&amp;quot;&#39;&lt;/span&gt; % ( userid, base64.b64encode( digest), base64.b64encode( nonce), created)


    headers = { &lt;span class=&quot;synConstant&quot;&gt;&amp;quot;X-WSSE&amp;quot;&lt;/span&gt;: make_wsse( userid, apikey)}
    request = urllib2.Request( apiurl, headers=headers)
    response = urllib2.urlopen( request)
    &lt;span class=&quot;synIdentifier&quot;&gt;print&lt;/span&gt; response.read()
    &lt;/pre&gt;
    &lt;table&gt;
    &lt;tr&gt;
    &lt;td&gt;userid&lt;/td&gt;
    &lt;td&gt;ログイン等に使うユーザ名&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
    &lt;td&gt;apikey&lt;/td&gt;
    &lt;td&gt;ブログの詳細設定にきさいされている&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/API&quot;&gt;API&lt;/a&gt;キー&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
    &lt;td&gt;blogid&lt;/td&gt;
    &lt;td&gt;mon0.hatebalog.jp等のURL。ブログの基本設定にブログURLとして記載&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/table&gt;&lt;p&gt;これを変更すればそのまま使える。実行すると直近の記事7件(10件?)に関連する&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Atom&quot;&gt;Atom&lt;/a&gt;が出力される。&lt;/p&gt;&lt;br /&gt;
    &lt;p&gt;&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0&quot;&gt;はてなブログ&lt;/a&gt;のAtomPub &lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/API&quot;&gt;API&lt;/a&gt;&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Basic%C7%A7%BE%DA&quot;&gt;Basic認証&lt;/a&gt;、WSSE認証、OAuthに対応している様子。&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Basic%C7%A7%BE%DA&quot;&gt;Basic認証&lt;/a&gt;は試していないが最も単純に認証を行えるかと思う。だが&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Basic%C7%A7%BE%DA&quot;&gt;Basic認証&lt;/a&gt;はセキュリティ的にあんまりよくなさそうなのでWSSE認証を選択した。世間的にはOAuthがベターかと思うが、アプリケーションの登録が必要などサンプルコード以外の説明も必要になるためWSSE認証とした。&lt;/p&gt;&lt;p&gt;また、先の&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/API&quot;&gt;API&lt;/a&gt;説明ページでは&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Atom&quot;&gt;Atom&lt;/a&gt;の解析までおこなっているようだが、このサンプルでは生の&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/XML&quot;&gt;XML&lt;/a&gt;を取得するまでとする。この&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/XML&quot;&gt;XML&lt;/a&gt;&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/API&quot;&gt;API&lt;/a&gt;説明ページの内容とは少々異なるため、ドキュメントの内容から少々更新されているのかも知れない。また、ドキュメントには&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/XML&quot;&gt;XML&lt;/a&gt;のフォーマットまで解説されていないので近日中に&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/XML&quot;&gt;XML&lt;/a&gt;のフォーマットを確認し記事にしようかと思う。&lt;/p&gt;&lt;p&gt;コードを変更する際は誤ってDELETE命令を出さないように注意。DELETEするともちろん復元することができない。&lt;/p&gt;&lt;br /&gt;
    &lt;p&gt;&lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0&quot;&gt;はてなブログ&lt;/a&gt;にはエクスポート機能が提供されていないが、このAtomPub &lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/API&quot;&gt;API&lt;/a&gt;を用いることで全記事を取得できるようなのでエクスポート機能を実装できるかと思う。これも近日中に作成して記事にしようかと思う。&lt;/p&gt;&lt;p&gt;&lt;div class=&quot;hatena-asin-detail&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/4774142298/mon0-22/&quot;&gt;&lt;img src=&quot;http://ecx.images-amazon.com/images/I/51KkpibMKqL._SL160_.jpg&quot; class=&quot;hatena-asin-detail-image&quot; alt=&quot;Pythonスタートブック&quot; title=&quot;Pythonスタートブック&quot;&gt;&lt;/a&gt;&lt;div class=&quot;hatena-asin-detail-info&quot;&gt;&lt;p class=&quot;hatena-asin-detail-title&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/4774142298/mon0-22/&quot;&gt;Pythonスタートブック&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;作者:&lt;/span&gt; 辻真吾&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;出版社/メーカー:&lt;/span&gt; &lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2&quot;&gt;技術評論社&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;発売日:&lt;/span&gt; 2010/04/24&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;メディア:&lt;/span&gt; 大型本&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;購入&lt;/span&gt;: 19人 &lt;span class=&quot;hatena-asin-detail-label&quot;&gt;クリック&lt;/span&gt;: 199回&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://d.hatena.ne.jp/asin/4774142298/mon0-22&quot; target=&quot;_blank&quot;&gt;この商品を含むブログ (40件) を見る&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class=&quot;hatena-asin-detail-foot&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;hatena-asin-detail&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/477415539X/mon0-22/&quot;&gt;&lt;img src=&quot;http://ecx.images-amazon.com/images/I/51qCCa-gPLL._SL160_.jpg&quot; class=&quot;hatena-asin-detail-image&quot; alt=&quot;パーフェクトPython (PERFECT SERIES 5)&quot; title=&quot;パーフェクトPython (PERFECT SERIES 5)&quot;&gt;&lt;/a&gt;&lt;div class=&quot;hatena-asin-detail-info&quot;&gt;&lt;p class=&quot;hatena-asin-detail-title&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/477415539X/mon0-22/&quot;&gt;パーフェクトPython (PERFECT SERIES 5)&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;作者:&lt;/span&gt; &lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/Python&quot;&gt;Python&lt;/a&gt;サポーターズ&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;出版社/メーカー:&lt;/span&gt; &lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2&quot;&gt;技術評論社&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;発売日:&lt;/span&gt; 2013/03/05&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;メディア:&lt;/span&gt; 大型本&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;購入&lt;/span&gt;: 1人 &lt;span class=&quot;hatena-asin-detail-label&quot;&gt;クリック&lt;/span&gt;: 65回&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://d.hatena.ne.jp/asin/477415539X/mon0-22&quot; target=&quot;_blank&quot;&gt;この商品を含むブログ (16件) を見る&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class=&quot;hatena-asin-detail-foot&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;hatena-asin-detail&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/4774142042/mon0-22/&quot;&gt;&lt;img src=&quot;http://ecx.images-amazon.com/images/I/51qo6pgjaSL._SL160_.jpg&quot; class=&quot;hatena-asin-detail-image&quot; alt=&quot;Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)&quot; title=&quot;Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)&quot;&gt;&lt;/a&gt;&lt;div class=&quot;hatena-asin-detail-info&quot;&gt;&lt;p class=&quot;hatena-asin-detail-title&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/4774142042/mon0-22/&quot;&gt;Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;作者:&lt;/span&gt; 山本陽平&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;出版社/メーカー:&lt;/span&gt; &lt;a class=&quot;keyword&quot; href=&quot;http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2&quot;&gt;技術評論社&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;発売日:&lt;/span&gt; 2010/04/08&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;メディア:&lt;/span&gt; 単行本(ソフトカバー)&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;購入&lt;/span&gt;: 143人 &lt;span class=&quot;hatena-asin-detail-label&quot;&gt;クリック&lt;/span&gt;: 4,320回&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://d.hatena.ne.jp/asin/4774142042/mon0-22&quot; target=&quot;_blank&quot;&gt;この商品を含むブログ (174件) を見る&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class=&quot;hatena-asin-detail-foot&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;hatena-asin-detail&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/0470087889/mon0-22/&quot;&gt;&lt;img src=&quot;http://ecx.images-amazon.com/images/I/51Vzqdh8XQL._SL160_.jpg&quot; class=&quot;hatena-asin-detail-image&quot; alt=&quot;Professional Web 2.0 Programming (Wrox Professional Guides)&quot; title=&quot;Professional Web 2.0 Programming (Wrox Professional Guides)&quot;&gt;&lt;/a&gt;&lt;div class=&quot;hatena-asin-detail-info&quot;&gt;&lt;p class=&quot;hatena-asin-detail-title&quot;&gt;&lt;a href=&quot;http://www.amazon.co.jp/exec/obidos/ASIN/0470087889/mon0-22/&quot;&gt;Professional Web 2.0 Programming (Wrox Professional Guides)&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;作者:&lt;/span&gt; Eric van der Vlist,Danny Ayers,Erik Bruchez,Joe Fawcett,Alessandro Vernet&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;出版社/メーカー:&lt;/span&gt; Wrox&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;発売日:&lt;/span&gt; 2006/11/29&lt;/li&gt;&lt;li&gt;&lt;span class=&quot;hatena-asin-detail-label&quot;&gt;メディア:&lt;/span&gt; ペーパーバック&lt;/li&gt;&lt;li&gt; &lt;span class=&quot;hatena-asin-detail-label&quot;&gt;クリック&lt;/span&gt;: 11回&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://d.hatena.ne.jp/asin/0470087889/mon0-22&quot; target=&quot;_blank&quot;&gt;この商品を含むブログを見る&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class=&quot;hatena-asin-detail-foot&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;
  </hatena:formatted-content>

  <category term="はてな" />

  <category term="Python" />

  <app:control>
    <app:draft>no</app:draft>
  </app:control>

</entry>

</feed>


実際にコレクションを取得した際はentryブロックが10個挿入されていることになるが今回はフォーマットの確認なので除去した。上にも書いたが「ブログエントリの一覧取得」では「一度に7件のブログエントリを取得できます。」とあるが、現在(私の環境で)は10件取得できた。これについては近日中にはてなに問い合わせる。

このXMLは少々読みづらいため整形して内容をまとめると以下になる。

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:app="http://www.w3.org/2007/app">

  <link rel="first" href="http://blog.hatena.ne.jp/mon0/mon0.hatenablog.jp/atom/entry" />
  <link rel="next" href="http://blog.hatena.ne.jp/mon0/mon0.hatenablog.jp/atom/entry?page=1392811641" />
  <title>起業と読書と人生と</title>
  <subtitle>起業への活動と、日々の読書と、人生について書かれた紙片</subtitle>
  <link rel="alternate" href="http://blog.mon0.jp/"/>
  <updated>2014-02-26T10:52:17+09:00</updated>
  <author>
    <name>mon0</name>
  </author>
  <generator uri="http://blog.hatena.ne.jp/" version="ad4baa17ce5956c437352b80fe3669ae">Hatena::Blog</generator>
  <id>hatenablog://blog/11696248318755645593</id>
  <entry>
    <id>tag:blog.hatena.ne.jp,2013:blog-mon0-11696248318755645593-12921228815719030568</id>
    <link rel="edit" href="http://blog.hatena.ne.jp/mon0/mon0.hatenablog.jp/atom/entry/12921228815719030568"/>
    <link rel="alternate" type="text/html" href="http://blog.mon0.jp/entry/2014/02/26/105217"/>
    <author><name>mon0</name></author>
    <title>エントリタイトル</title>
    <updated>2014-02-26T10:52:17+09:00</updated>
    <published>2014-02-26T10:52:17+09:00</published>
    <app:edited>2014-02-26T10:52:17+09:00</app:edited>
    <summary type="text">エントリのサマリ。はてなが自動で生成するかユーザが入力したものが挿入される。</summary>
    <content type="text/x-hatena-syntax">
      はてな記法で入力しているためココには実際に入力したはてな記法の生データが挿入される。「はてな記法」モードではなく「見たままモード」であれば"text/html"として入力した内容が挿入される。
    </content>
    <hatena:formatted-content type="text/html" xmlns:hatena="http://www.hatena.ne.jp/info/xmlns#">
      はてな入力モードに従いHTMLに変換したものが挿入される。「見たままモード」でもはてなが変換したHTMLがココに挿入される模様。
    </hatena:formatted-content>

    <category term="カテゴリ名1" />
    <category term="カテゴリ名2" />

    <app:control>
      <app:draft>no</app:draft>
    </app:control>

  </entry>
</feed>


これが基本的なフォーマットになる。feedのauthorとentryのauthorが別々になっているということは、ブログ所有者でなくてもエントリを投稿できるのであろうか?そのような設定は見つけることが出来なかった。これについてわかる人がいれば教えてほしい。

「link rel="next"」は記事が10以下のブログでは挿入されない。ページリクエストを順次出したら最後のコレクションでも挿入されない。これを辿っていけば10件づつ全ての記事を取得できはてなブログのエクスポートが実装できるかと思う。後ほどこれを実証して別の記事にする。


エントリブロックは以下の要素が基本になる。

id 多分はてな内部の識別ID。ユーザ側ではこれを使った情報は見つけられなかった。
link rel="edit" 記事を編集する際のAtomPub URL
link rel="alternate" 記事が公開されているURL
author > name 記事の投稿者ID
title 記事タイトル
updated 記事の公開日時?
published 記事を書いた日時?
app:edited 記事を変更した日時?
summary 記事の概要
content 入力したモード別の生データ
hatena:formatted-contetn はてながcontentをHTMLに変換した結果。Amazon等のアソシエイトについてもHTMLに変換したものが挿入される。
category カテゴリ名称。複数挿入することで複数のカテゴリを関連付ける
app:control > app:draft 記事が下書きかどうか


えらくシンプル。日時系の違いは調査しないとわからないがエクスポートするには関係ないので調査していない。それぞれがアップロード日時、公開日時、編集日時にあたると思う。とりあえずエクスポートするには公開日時としてupdatedを取得しておけばいい。


コメントが入るかどうかは私のブログにコメントがないためわからない。どなたかがコメントをくれるとコメントが付加されるか確認できる。誰かコメントを下さい。

「へんな会社」のつくり方 (NT2X)

「へんな会社」のつくり方 (NT2X)