Ubuntu 15.10 には python3-googleapi というパッケージがあり、これを使うと Python3 スクリプトから Google Blogger に投稿できるはずなのですが、途中でエラーとなりいまいち解決方法がわかりませんでした。
なので今回は Python2.7 スクリプトから Google API を利用して Gooble Blogger へ投稿してみました。OS はいつもどおり Ubuntu 14.04 LTS です。
環境
- Ubuntu 14.04 Server
- Python 2.7.6
Blogger API V3 を有効にする
スクリプトから Blogger へ投稿するために Google API を使うには、スクリプトを OAuth 2.0 で Google に認証してもらう必要があります。まずは Blogger 用 Google API を有効にして OAuth 2.0 認証情報を Google から取得します。
Google デベロッパーコンソールにアクセス
プロジェクトを作成
- プロジェクト名: (任意)
- App Engine の場所: us-central (デフォルトのまま)
Blogger API V3 を有効化
- デベロッパーコンソールで作成したプロジェクトの API Manager に移動
- Google デベロッパーコンソールの画面左上をクリックすると出てくるメニューで「API Manager」をクリック
- 「概要」タブをクリック
- API 検索ボックスに「Blogger」を入力
- 「Blogger API V3」をクリック
- 「API を有効にする」をクリック
- 「有効な API」に「Blogger API V3」が追加されました。
- 他にもいろいろな API がデフォルトで有効になっていますが、必要なさそうなので「Blogger API V3」以外は無効にしておきます。
OAuth 同意画面を設定
- API Manager の画面で「認証情報」タブの中の「OAuth 同意画面」をクリック
- 「ユーザーに表示するサービス名 」を設定 (必須の設定のようです)
- その他の項目も必要に応じて設定
- 「保存」をクリック
認証情報を設定
- API Manager の画面で「認証情報」タブの中の「認証情報」をクリック
- 「新しい認証情報」のドロップダウンから「OAuth クライアント ID」を選択
- アプリケーションの種類で「その他」を選択
- クライアント名を入力
- 「作成」をクリック
- 「クライアント ID」と「クライアント シークレット」が作成されました。
Ubuntu 側の準備
Google API モジュールをインストール
$ sudo apt-get install python-googleapi
クライアント シークレット JSON ファイルを配置
Google API Manager からクライアントシークレット JSON ファイル client_secret_...json (省略してますが、かなり長いファイル名です) をダウンロード
ダウンロードした client_secret_...json を some/where/client_secret.json として配置
クレデンシャル情報保存用のテンポラリなファイルを作成
$ touch some/where/tmp_credentials
これらのファイルは他の人に見られるのは良くなさそうなので、アクセス権を変更
$ chmod 600 some/where/client_secret.json some/where/tmp_credentials
- これはとりあえずの chmod ですが、心配であればさらに厳しいアクセス制限をお勧めします。
Python2.7 から Gloogle Blogger API へアクセス
Python2.7 を起動
$ python2.7
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
モジュールをインポート
>>> from oauth2client import client
>>> from apiclient.discovery import build
>>> import httplib2
>>> from pprint import pprint
tmp_credentials ファイルからクレデンシャル情報 (oCredentials) を取得
>>> def getCredentialsFromFile():
... with open('some/where/tmp_credentials') as oFileCredentials:
... sCredentials = oFileCredentials.read()
...
... try:
... oCredentials = client.OAuth2Credentials.from_json(sCredentials)
... except:
... return None
...
... if oCredentials.invalid:
... return None
...
... return oCredentials
...
>>> oCredentials = getCredentialsFromFile()
- 初めてこのコードを実行する場合は tmp_credentials は空ファイルなので oCredentials は None となります。
- 2度目以降は tmp_credentials から読み込んだクレデンシャル情報が oCredentials にセットされます。
tmp_credentials ファイルからクレデンシャル情報を取得できなかった場合は OAuth2 で Google API からクレデンシャル情報を取得
>>> if oCredentials is None:
... oFlow = client.flow_from_clientsecrets(
... 'some/where/client_secret.json',
... scope='https://www.googleapis.com/auth/blogger',
... redirect_uri='urn:ietf:wg:oauth:2.0:oob'
... )
... sAuthUrl = oFlow.step1_get_authorize_url()
... print(sAuthUrl)
...
https://accounts.google.com/o/oauth2/auth?scope=...
表示された URL にブラウザでアクセスし、得られた認証コードを以下のように入力
>>> if oCredentials is None:
... sAuthCode = raw_input('Authorization code: ')
... oCredentials = oFlow.step2_exchange(sAuthCode)
...
... with open('some/where/tmp_credentials', 'r+') as oFileCredentials:
... oFileCredentials.truncate(0)
... oFileCredentials.write(oCredentials.to_json())
...
Authorization code: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
クレデンシャル情報 (oCredentials) を取得することができたので Blogger サービスオブジェクト (oBloggerService) を取得
>>> oHttp = httplib2.Http()
>>> oHttp = oCredentials.authorize(oHttp)
>>> oBloggerService = build(serviceName='blogger', version='v3', http=oHttp)
ユーザー情報を表示
>>> oUsers = oBloggerService.users()
>>> dUser = oUsers.get(userId='self').execute()
>>> pprint(dUser)
{u'about': u'',
u'blogs': {u'selfLink': u'https://www.googleapis.com/blogger/v3/users/XXXXXXXXXXXXXXXXXXXXXX/blogs'},
u'displayName': u'Shrimper Fish',
u'id': u'XXXXXXXXXXXXXXXXXXXXXX',
u'kind': u'blogger#user',
u'selfLink': u'https://www.googleapis.com/blogger/v3/users/XXXXXXXXXXXXXXXXXXXXXX',
u'url': u'https://www.blogger.com/profile/YYYYYYYYYYYYYYYYYYYY'}
ブログ情報を表示
>>> oBlogs = oBloggerService.blogs()
>>> dBlogs = oBlogs.listByUser(userId='self').execute()
>>> pprint(dBlogs)
{u'items': [{u'description': u'',
u'id': u'ZZZZZZZZZZZZZZZZZZZ',
u'kind': u'blogger#blog',
u'locale': {u'country': u'',
u'language': u'ja',
u'variant': u''},
u'name': u'IT とかその他もろもろ',
u'pages': {u'selfLink': u'https://www.googleapis.com/blogger/v3/blogs/ZZZZZZZZZZZZZZZZZZZ/pages',
u'totalItems': 0},
u'posts': {u'selfLink': u'https://www.googleapis.com/blogger/v3/blogs/ZZZZZZZZZZZZZZZZZZZ/posts',
u'totalItems': 126},
u'published': u'2012-03-23T22:19:00+09:00',
u'selfLink': u'https://www.googleapis.com/blogger/v3/blogs/ZZZZZZZZZZZZZZZZZZZ',
u'status': u'LIVE',
u'updated': u'2016-02-18T02:47:00+09:00',
u'url': u'http://fishrimper.blogspot.com/'}],
u'kind': u'blogger#blogList'}
- Python2.7 の pprint で日本語を表示しようとすると文字化けするので修正しています。
記事を投稿するブログの ID を取得
>>> sID = dBlogs['items'][0]['id']
>>> sID
u'ZZZZZZZZZZZZZZZZZZZ'
記事を投稿
>>> dBody = {
... 'title': 'Test Title',
... 'content': '<div>Test Content</div>'
... }
>>> oPosts = oBloggerService.posts()
>>> dResult = oPosts.insert(blogId=sID, body=dBody, isDraft=True).execute()
>>> pprint(dResult)
{u'author': {u'displayName': u'Shrimper Fish',
u'id': u'XXXXXXXXXXXXXXXXXXXXXX',
u'image': {u'url': u'//XXX.googleusercontent.com/XXXXXXXXXX/AAAAAAAAAAI/AAAAAAAAAMc/XXXXXXXX/XXXXX/photo.jpg'},
u'url': u'https://www.blogger.com/profile/YYYYYYYYYYYYYYYYYYYY'},
u'blog': {u'id': u'ZZZZZZZZZZZZZZZZZZZ'},
u'content': u'<div>Test Content</div>',
u'etag': u'"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"',
u'id': u'XXXXXXXXXXXXXXXXXX',
u'kind': u'blogger#post',
u'published': u'2016-02-19T13:26:00+09:00',
u'readerComments': u'ALLOW',
u'replies': {u'selfLink': u'https://www.googleapis.com/blogger/v3/blogs/ZZZZZZZZZZZZZZZZZZZ/posts/XXXXXXXXXXXXXXXX/comments',
u'totalItems': u'0'},
u'selfLink': u'https://www.googleapis.com/blogger/v3/blogs/ZZZZZZZZZZZZZZZZZZZ/posts/XXXXXXXXXXXXXXXXXXXXXXXX',
u'status': u'DRAFT',
u'title': u'Test Title',
u'updated': u'2016-02-19T13:26:33+09:00',
u'url': u'http://fishrimper.blogspot.com/'}
dBody の内容が草稿として Blogger に投稿されました。
参考
- http://google-api-python-client.googlecode.com/hg/docs/epy/oauth2client.client-module.html
- https://developers.google.com/api-client-library/python/guide/aaa_oauth
- https://developers.google.com/api-client-library/python/
- https://developers.google.com/blogger/docs/3.0/api-lib/python
- http://www.joyofdata.de/blog/oauth2-google-api-python-google-analytics/
- https://github.com/joyofdata/joyofdata-articles/tree/master/oauth2-google-api
- http://joke-tech.blogspot.jp/2014/01/googleoauth20.html
- http://blog.mwsoft.jp/article/106365724.html
0 件のコメント:
コメントを投稿