Milkのメモ帳

日々の思いつきを忘れないようにのメモ用です。

Milkのメモ帳

【はてなブログAtomPub】はてなAPIの利用方法(1)


f:id:maxminkun:20171002204854p:plain

こんにちは。Milkです。
はてなブログはWebAPIを公開しています。なので、ちょっと色々と試してみました。

先日の記事で、HTTPS化に伴い「自分の記事のリンク」のリンク切れを防止する方法を紹介しました。

www.milkmemo.com

リンク切れ対策はこれではまだ不十分で、誰かの「はてなブログ」の記事を言及した場合は、軒並みリンク切れを起こすと考えられます。

しかし、これは「自分のドメイン」で検索をかけるという方法では見つからないし、そもそも独自ドメインならば「はてなブログ」かどうかは判断つきません。

と言うことは、やはり実際に見てみてリンク切れを起こしているのを修正しなければなりません。

また、問題点としてインポートをかけると、全てが「見たままモード」になります。

これも私にとっては都合が悪い。メンテナンス性が落ちる・・・(´;ω;`)

要約すると、問題点は以下の2点になります。

  • HTTPのリンクを貼っている記事を検出したい
  • データインポートした時に、「見たままモード」を回避したい

となります。

はてなWebAPI(はてなブログAtomPub)

ちょっと頭を整理するために書いていくので、内容がちぐはぐになるかも知れません。
(申し訳ない。)

  1. データエクスポート
  2. 自分のドメインのリンクをHTTPSに置換
  3. データインポート

これが基本的な流れですが、しかしこのままでは「HTTP」から「HTTPS」に対応した他人の記事があった場合、リンク切れを起こします。

一つの手としては、2番の時点で検索をかけて探し出すという手段です。

例えばこういうことです。

<!-- 置換前 -->
<a href="http://・・・"></a>

<!-- 置換後 -->
<a href="https://・・・"></a>

また、恐らくAMPに対応するためのタグと思われますが、以下の部分も修正が必要です。

<!-- 置換前 -->
<iframe src="http://・・・"></iframe>

<!-- 置換後 -->
<iframe src="https://・・・"></iframe>

まぁ・・・結局のところ、「HTTP」の状態になっているものは、全て洗ったほうがいいのですが、なにせエクスポートした時には全ての記事が一つのファイルの中に出力されます。

これをだらだらと眺めて、

該当する・・・該当しない・・・該当する・・・該当しない・・・

と選別するのは面倒。

また、頑張って直したところで、最後はまとめてインポートするので「見たままモード」になります。

嫌だ・・・嫌すぐる!

と言うわけで、前置きが長くなったんですけど、どうやら「はてな」が公開しているWebAPIを経由すれば、個別に編集が可能っぽいです。

はてなWebAPIで出来ること

そもそもWebAPIに疎いので、使い方が分からない・・・(;・∀・)

アプリケーションプログラミングインタフェース(API、英: Application Programming Interface)とは、ソフトウェアコンポーネントが互いにやりとりするのに使用するインタフェースの仕様である。
参照:アプリケーションプログラミングインタフェース - Wikipedia

APIとは簡単に言うと、他の人が作ったプログラムを利用できる仕組みのことです。

ただし、昔から(今もですが)そのプログラムをコンピュータの内部に置いて、そして参照する形が多かったのです。

ですがWebAPIと言うのは、どこか遠くにあるWebサーバ(インターネットでつながっているコンピュータ)に対して、「こういうことしたいので処理を頼んだ!結果をください!」と頼む形なんです。

その頼み方も、ちょっと今までのAPIの利用の仕方と異なりますので、使い方が私はまだピンと来てないんですね・・・(´;ω;`)

「はてなブログ」が公開してるWebAPIは以下のものがあります。

はてなブログAtomPub - Hatena Developer Center

出来ることは以下のようなものです。

  • サービス文書の取得
  • ブログエントリ(記事)の一覧取得
  • ブログエントリ(記事)の投稿
  • ブログエントリ(記事)の取得
  • ブログエントリ(記事)の編集
  • ブログエントリ(記事)の削除
  • カテゴリ文書の取得

この中で、魅力的なのは「ブログエントリ(記事)の編集」です。

記事を投稿した場合は以下のことが適用されるようです。

コレクションURIに対して XML 文書を POST することで、ブログエントリを投稿できます。
このブログエントリは、ブログに登録された記法で書かれたものであると解釈されます。
参照:はてなブログAtomPub - Hatena Developer Center

また、これは編集のときにも同様に適用されるとのこと。

つまり?

<?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>
  <author><name>name</name></author>
  <content type="text/plain">
    ** エントリ本文
  </content>
  <updated>2008-01-01T00:00:00</updated>
  <category term="Scala" />
  <app:control>
    <app:draft>{yes | no}</app:draft>
  </app:control>
</entry>

こういった形の文章を、「POST」では投稿になりますが、「PUT」と言う命令で処理をお願いすると編集扱いになり、「はてな記法」で上書きされるようです。

<content></content>の間に挟まれた部分が**となっていますね。

これは「はてな記法」で言う、「大見出し」になります。

「Markdown記法」では##に該当します。
(厳密に言うと、「はてな記法」では<h3>、「Markdown記法」では<h2>に該当します。)

どうやら、記法はWebサーバ側が判断するみたいですね。

ここで一つ仮説が立てられます。

  1. エクスポートしたデータを記事ごとに分割する
  2. 記事の中から自動で「HTTP」を検出し記事の選別を行う
  3. 必要なら修正を行う(ここは手動)
  4. 見出しを必要な記法で置き換え、編集が必要な記事のみを「はてなWebAPI」経由で編集する

これなら、ブログに対して必要最低限の操作で記事の修正をしていくことが出来ます。

プログラムの組み方次第では、過去の記事を一括で「記法」の統一も行うことが出来る。

実は、私のは初期は「見たままモード」で、途中から「はてな記法」、最終的には「Markdown記法」と書き方を変更しています。

一度投稿すると、記法の修正がかけられないんですよね・・・

仮にWebAPIが上書きで受け付けてくれるなら、過去記事の「記法」の統一も夢ではない?!
(既存の記事と記法が異なるとなって、受け付けてくれない可能性はある・・・)

とりあえずGETで操作できるAPIを試してみる

プログラムを書いてみるのでも良いのですが、まずは実際にAPIが利用できるのか確認してみたいと考えました。

また、どうしても編集の際には「どの記事なのか」を特定するための、特殊なキーが必要なので、それも取得しなければなりません。

一番簡単な、GETを利用したAPIを試してみることにしました。

これを選んだ理由は、WebブラウザのURLを入力してEenterキーを押すことは「GET」を送信していることと同じだからです。

実は、URLを入力するとWebブラウザは「GET」と言う命令と共に、このURLを送ります。

意味としては、「このURLに該当するファイルをGETしたいです!」と言うことです。

そう言われると、Webサーバはそれに該当するデータを、GETを求めてきたコンピュータに返信します。

「GET」で試せるWebAPIは取得系ですので、

  • ブログエントリ(記事)の一覧取得
  • ブログエントリ(記事)の取得

などが試せます。

ブログエントリ(記事)の一覧取得

これは記事の内容をごっそり取得できます。

ただし制約があって、直近の7件までです。

例としては

GET https://blog.hatena.ne.jp/{はてなID}/{ブログID}/atom/entry
GET https://blog.hatena.ne.jp/{はてなID}/{ブログID}/atom/entry?page=1377575606

が挙げられています。

  • はてなID:はてなブログで使用しているID
  • ブログID:ブログドメイン
    (独自ドメインではなく、はてなから割り当てられているドメインです。「設定」-「基本設定」-「ブログURL」にあります。)

つまり、Webブラウザに「https://blog.hatena.ne.jp/{はてなID}/{ブログID}/atom/entry」を入力します。

すると、7件分の記事がXMLと言うデータ形式で表示されるはずです。

この時にログインを求められます。

f:id:maxminkun:20171002194441p:plain


  • ユーザー名:はてなID
  • パスワード:APIキー

になります。APIキーとは、「設定」-「詳細設定」-「AtomPub」-「APIキー」に書かれているものです。

f:id:maxminkun:20171002195111p:plain


これは他人には分からないようにして下さい。

そうでないと、他人が記事の情報取得や編集などが出来るようになってしまいます。

さて、入力が完了すれば記事の一覧を取得出来ます。

f:id:maxminkun:20171002195409p:plain


見にくいので、VSCodeに.xmlとして表示し直しましょうか。

f:id:maxminkun:20171002195711p:plain


注目してほしいのは以下の部分です。

<link rel="next" href="https://blog.hatena.ne.jp/maxminkun/maxminkun.hatenablog.jp/atom/entry?page=1468914259" />

最初の7件は「entry」で終われば良いのですが、次の7件を取得するには「entry?page=数列」という具合に、どのページを取得するのか?と言うパラメータが必要です。

しかし試したところ、この数列の規則性は分かりません(汗)

番号がふられていると考えたほうが良いでしょう。

ですから、XMLを順番に7件ずつ取得していかないと、次の「entry?page=数列」は分かりません。

最終的に、この<link rel="next"・・・/>が表示されなくなれば、最後のページまで到達したことになります。

こうやって記事を取得することが出来るのです。

ブログエントリ(記事)の取得

単純に1つの記事を取得したい場合はどうしたらよいのでしょう?

例としては、

GET https://blog.hatena.ne.jp/{はてなID}/{ブログID}/atom/entry/{entry_id}

となっています。

ここで問題になるのは、「entry_id」です。

これはどこから分かるのか・・・

実は、記事一覧を取得したら分かるのです(汗)

私のある記事を抽出してみます。

<id>tag:blog.hatena.ne.jp,2013:blog-maxminkun-8599973812298930376-8599973812303233549</id>
<link rel="edit" href="https://blog.hatena.ne.jp/maxminkun/maxminkun.hatenablog.jp/atom/entry/8599973812303233549"/>
<link rel="alternate" type="text/html" href="http://maxminkun.hatenablog.jp/entry/2016/07/21/222841"/>
<author><name>maxminkun</name></author>
<title>Webページひとつで地方と都心の格差を感じてしまった</title>
<updated>2016-07-21T22:28:41+09:00</updated>
<published>2016-07-21T22:28:41+09:00</published>
<app:edited>2017-10-01T10:13:48+09:00</app:edited>
<summary type="text"></summary>
<content type="text/html">&lt;p&gt;&lt;span itemscope itemtype=&quot;http://schema.org/Photograph&quot;&gt;&lt;img src=&quot;https://cdn-ak.f.st-hatena.com/images/fotolife/m/maxminkun/20160721/20160721200505.jpg&quot; alt=&quot;f:id:maxminkun:20160721200505j:plain&quot; title=&quot;f:id:maxminkun:20160721200505j:plain&quot; class=&quot;hatena-fotolife&quot; itemprop=&quot;image&quot;&gt;&lt;/span&gt;&lt;br /&gt;

その中でも、この部分に注目です。

<link rel="edit" href="https://blog.hatena.ne.jp/maxminkun/maxminkun.hatenablog.jp/atom/entry/8599973812303233549"/>

「entry」の後ろに番号が付いていますよね?

この番号が記事固有にふられた「entry_id」になりますし、そもそも「https://・・・」を全てブラウザのURLに入力してしまえば、その記事だけを取り出せます。

f:id:maxminkun:20171002201922p:plain

他の操作は?

ブラウザで操作出来るのは、GET操作だけです。

ですから、編集等はPUTと言った命令を送らなければならないのですが、これはプログラムから色々値を設定して行わなければなりません。

現段階では、やっとGET操作によって何が出来るかが分かったところです(;・∀・)

今の考えでは、データエクスポートとPUTによるWebAPIを組み合わせれば、「Markdown記法」や「はてな記法」として上手く編集が出来るのでは?と考えています。

しかし、ここはプログラムで通信部分を上手く組まなければなりません。

ちょいと時間を見つけて、この部分の実装は考えてみます。

最後に

この、GET操作はブラウザから出来るので、皆さんも試してみてください。

こうやってデータを受信出来る仕組みは面白いと思います。

私も色々調べて実践したことで、やっと「はてなブログ」のデータ部分の理解が出来ました。

かなり専門的な知識でしたが、備忘録として記録します。

それでは今回はこの辺で。

adios!!