はじめに
はてなブログの自動投稿は以下で記事にしましたが
写真投稿も自動で行うことで自動投稿の中に新規画像を入れ込むためにPythonコードでのアップロードをテストしました。
環境情報
# python3.6 --version Python 3.6.3
Pythonコード
以下コードのidにはてなID、api_keyにはてなブログの詳細設定で確認できるAPIキーを入力します。
またFotolife > My fotolife > tmp というフォルダに格納するようにしていますが、それ以外の場所に配置する場合はその部分を修正します。
# -*- coding: utf-8 -*- from base64 import b64encode from datetime import datetime from hashlib import sha1 import random import requests import sys from pathlib import Path username = 'XX' api_key = 'XX' def wsse(username: str, api_key: str) ->str: created = datetime.now().isoformat() + "Z" b_nonce = sha1(str(random.random()).encode()).digest() b_digest = sha1(b_nonce + created.encode() + api_key.encode()).digest() return f'UsernameToken Username="{username}", PasswordDigest="{b64encode(b_digest).decode()}", Nonce="{b64encode(b_nonce).decode()}", Created="{created}"' def create_data(file_name: str='./test.png') ->str: uploadData = b64encode(Path(file_name).read_bytes()) return """ <entry xmlns="http://purl.org/atom/ns#"> <title>Sample</title> <content mode="base64" type="image/png">""" + uploadData.decode() + """</content> <generator>tmp</generator> </entry> """ def post_hatena(data): headers = {'X-WSSE': wsse(username, api_key)} url = 'https://f.hatena.ne.jp/atom/post/' r = requests.post(url, data=data, headers=headers) try: r.raise_for_status() except: sys.stderr.write(f'Error!\nstatus_code: {r.status_code}\nmessage: {r.text}') print('text = ' + r.text) def main(): data = create_data() post_hatena(data) if __name__ == '__main__': main()
実行結果
上記スクリプトを引数なしで実行すると標準出力にて以下が応答で返ってきます。
text = <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://purl.org/atom/ns#" xmlns:hatena="http://www.hatena.ne.jp/info/xmlns#"> <title>Sample</title> <link rel="alternate" type="text/html" href="http://f.hatena.ne.jp/xx/yy"/> <link rel="service.edit" type="application/x.atom+xml" href="http://f.hatena.ne.jp/atom/edit/yy" title="Sample"/> <issued>...</issued> <author> <name>xx</name> </author> <generator url="http://f.hatena.ne.jp/" version="1.0">Hatena::Fotolife</generator> <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">tmp</dc:subject> <id>tag:hatena.ne.jp,2005:fotolife-xx-yy</id> <hatena:imageurl>https://cdn-ak.f.st-hatena.com/images/fotolife/m/xx/yy.png</hatena:imageurl> <hatena:imageurlmedium>https://cdn-ak.f.st-hatena.com/images/fotolife/m/xx/yy_120.jpg</hatena:imageurlmedium> <hatena:imageurlsmall>https://cdn-ak.f.st-hatena.com/images/fotolife/m/xx/yy_m.jpg</hatena:imageurlsmall> <hatena:syntax>f:id:xx:yyp:image</hatena:syntax> </entry>
[f:id:xx:yyp:plain]
終わりに
モジュールがない場合は以下のようなエラーとなるため
# python3.6 test.py Traceback (most recent call last): File "test.py", line 5, in <module> import requests
個別に対応しました。
# pip3.6 install requests
あとはネット上にてサンプルコードがありましたが、Pythonのバージョンやhttps通信指定など細かな修正があったので今回は3.6で動作したコードをそのまま載せています。
ご参考ください。