Pythonでlivedoorのブログサービスに記事を取得・投稿する
livedoorブログへの投稿
livedoor blog
のサービスでは、AtomPub API
を使って記事の編集を行うことができる。
これをPython
で行う方法をメモとして残しておく。今回は、記事の取得と投稿を扱う。
公式ドキュメントを参考しつつ実装した: AtomPub API について - ライブドアブログのヘルプ(PC向け)
使用するPythonライブラリ
requests
(Requests: HTTP for Humans™ — Requests 2.24.0 documentation)でhttpリクエストを行う。
他はPythonの標準ライブラリでいい。
使用可能なAPI
公式ドキュメントから抜粋。URLをエンドポイントの末尾に付加して適切なメソッドでhttpリクエストを行う。
今回は記事の取得と投稿だけなので、使うURLはarticle
だけ。
URL | get | post |
---|---|---|
article | 最新20件の記事の取得 | 記事の投稿 |
APIを使う準備
当然のように認証が必要。https対応しているようなので、Basic認証でいいだろう。
認証で使うのは、ブログID(?)とAtomPub
用パスワード。どちらも、マイページ
-> ブログ設定
-> その他
カテゴリのAPI Key
のページを開いて確認できる。(公式ドキュメント参照のこと)
ブログIDはエンドポイントの末尾のパスの部分(最後のスラッシュより後ろの部分)のこと。
エンドポイントがhttps://livedoor.blogcms.jp/atompub/xxxabc123
ならブログIDはxxxabc123
ということになる。
Basic認証では、ブログIDがusername
に、AtomPub
用パスワードがpassword
になる。
サンプルコード
ここからは実装のサンプルを載せておく。
まずは共通の準備として、エンドポイントとパスワードとブログIDを保持する。ライブラリもインポートする。
# 共通の実装
import requests
from requests.auth import HTTPBasicAuth
ROOT_ENDPOINT = "https://livedoor.blogcms.jp/atompub/xxxabc123"
ATOM_PUB_PASS = "SOME_ATOMPUB_PASSWORD"
USERNAME = 'xxxabc123' # ブログID
xmlのパースと構築は、Pythonの標準ライブラリを使えばいい。ドキュメントはここ:xml.etree.ElementTree --- ElementTree XML API — Python 3.8.5 ドキュメント
記事の取得
記事の取得の場合は、取得したxmlをパースする必要がある。
# 記事取得のサンプル
def get_articles():
url: str = f'{ROOT_ENDPOINT}/article'
auth = HTTPBasicAuth(USERNAME, ATOM_PUB_PASS)
res = requests.get(url, auth=auth)
assert res.status_code == 200
print(res.content.decode('utf8')) # xml形式の文字列
あとはElementTree
でパースするなりすればいい。
記事の投稿
投稿ではxmlをポストする必要があり、文法ミスがある状態でリクエストを行うと400などのエラーになる。
xmlの内容は公式ドキュメントには詳しく書いてないので、同じくAtomPub
が利用できるはてなブログのドキュメントを参考にした。こちら:はてなブログAtomPub - Hatena Developer Center
RFC 5023 - The Atom Publishing Protocolを見るのが正確。
# 記事投稿のサンプル
import xml.etree.ElementTree as ET
def construct_xml_entry(title: str, msg: str) -> str:
""" 投稿用xmlの構築用関数 """
entry = ET.Element('entry',
attrib={
'xmlns': 'http://www.w3.org/2005/Atom',
'xmlns:app': 'http://www.w3.org/2007/app',
})
title_elm = ET.SubElement(entry, 'title')
title_elm.text = title
content_elm = ET.SubElement(entry, 'content', attrib={'type': 'text/html'})
content_elm.text = msg
# authorは省ける
app_ctrl = ET.SubElement(entry, 'app:control')
app_draft = ET.SubElement(app_ctrl, 'app:draft')
app_draft.text = 'yes' # noだと公開される
return ET.tostring(entry, encoding='unicode', xml_declaration=True)
def post_article():
url: str = f'{ROOT_ENDPOINT}/article'
auth = HTTPBasicAuth(USERNAME, ATOM_PUB_PASS)
headers = {'Content-Type': 'application/atom+xml;type=entry'}
xml = construct_xml_entry('タイトルになるよ',
'<span style="color: red;">タグも使える。</span>')
res = requests.post(url,
data=xml.encode('utf8'),
headers=headers,
auth=auth)
assert res.status_code == 201
おわり
記事の取得よりは投稿の方が使いたいので、そちらが重点的になってしまった。
xmlの仕様さえ分かればあまり難しいことではないようだ。
画像のアップロードや記事の削除・更新なども行える。この辺りはまた別で書くかもしれない。
また、実際にxmlを構築するのではなく、テンプレートを作ってそこへ埋め込んでいくのがいいと思う。 使い回しもできるし、xml全体の見通しも良くなる。
広告