それでは毛玉諸君、これにて失敬

日々の精進を備忘録的に綴ります。

はてなブログをAPI経由で投稿する

半年前は7kmくらい平気で走れたのに最近は1kmでバテバテ。ko_ya346です。
はてなブログへの投稿を快適にするために、API経由で記事を投稿できるようにしました。

動機は?

  • 最近webについて勉強していたので、GETとかPOSTとかしてみたかった
  • 使い慣れたエディタで記事が書ける
  • API使うという響きがかっこいいから

やってみた

最もシンプルな投稿手順は

  1. xml形式で記事を記述(sample.xml
  2. ブログの詳細設定からAPIキーを取得
  3. curlコマンドで投稿

かなと思ったので試してみました。
sample.xmlは公式のサンプルを流用してます。

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
       xmlns:app="http://www.w3.org/2007/app">
  <title>API経由ではてなブログを更新する</title>
  <author><name>virtual-surfer</name></author>
  <content type="text/markdown">
      # 見出し1
      aaa
      bbb

      # 見出し2
      - a
      - b
        - c
  </content>
  <category term="API" />
  <app:control>
    <app:draft>yes</app:draft>
  </app:control>
</entry>

あとは以下のコマンドを打つだけ

curl -XPOST -u {はてなid}:{APIキー} -d @sample.xml https://blog.hatena.ne.jp/{はてなID}/{ブログID}/atom/entry

結果

なんか崩れてる。。。
xmlファイルの記述について色々調べましたが素人には難しかったので断念。
他の方法を調べていると、md形式で記述した内容をxmlに吐き出すpythonスクリプトを紹介している記事を見つけたので、そちらの方法でやってみました。
以下スクリプト

from datetime import datetime
import requests

HATENA_ID = "{はてなID}"
BLOG_DOMAIN = "{ブログのドメイン}"
API_KEY = "APIー"
base_url = f"https://blog.hatena.ne.jp/{HATENA_ID}/{BLOG_DOMAIN}/atom"

def hatena_entry(title: str, content, categories=[], draft=True) -> None:
    """
    はてなブログへ投稿する
    """
    draft = "yes" if draft else "no"
    if len(categories) == 0:
        categories_tag = ""
    else:
        categories_tag = "\n".join([f"<category term='{category}' />" for category in categories])
    xml = f"""<?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/markdown">{content}</content>
    {categories}<app:control><app:draft>{draft}</app:draft>
    </app:control></entry>""".encode("UTF-8")

    ret = requests.post(base_url + "/entry", auth=(HATENA_ID, API_KEY), data=xml)
    return ret.text

if __name__ == "__main__":
    import sys

    _, arg = sys.argv
    with open(arg, "r") as f:
        title, categories, *content = f.readlines()
    categories = categories.split(",")
    content = "\n".join(content)
    ret = hatena_entry(title, content, categories)
    print(ret)

投稿するmdファイルはこんな感じ

# example.md
PIで記事を投稿
python

# 見出し
- a
- b
    - c

\```
print(1)
\```

> hogehoge

## abc

あとは実行するだけ

python3 main.py example.md

pythonスクリプトの実行結果

おおおお、出来た。いい感じですね。
画像アップロードするにはどうしたらいいか、とか
tex記法は使えるのか、URL貼った時は、、、など確認しないとですが、文章書いて投稿するだけなら便利かなと思いました。


ちなみにこの記事ははてブのエディタで書いてますw
スクリプトで投稿しようとしたらxmlのパースに失敗しました。
(多分途中にxmlの内容を書いてるからかなと思います)

参考

はてなブログAtomPub | Hatena Developer Center

はてなブログ自動投稿Pythonスクリプト :: tomowarkarの技術ブログ — 3歩進んで2歩下がる