Python, RequestsでWeb APIを呼び出し(データ取得・操作)

Posted: | Tags: Python, Requests, Web API

PythonのHTTPライブラリであるRequestsを使ってRESTスタイルのWeb APIを呼び出しデータを取得したり操作したりする方法について説明する。

Requestsのインストールや基本的な使い方などは以下の記事を参照。

Qiita APIを例に各HTTPメソッドでWeb APIを操作する。

以下の内容について説明する。

  • HTTPメソッド
  • Qiita APIのアクセストークン取得
  • POST(記事作成): requests.post()
  • GET(記事取得): requests.get()
  • PATCH(記事更新): requests.patch()
  • DELETE(記事削除): requests.delete()
  • PUT(タグフォロー): requests.put()

HTTPメソッド

目的に応じたHTTPメソッドによってWeb APIを呼び出す。HTTPメソッドについては以下のページを参照。

Web APIを操作するために使われる主なHTTPメソッドは以下の通り。

  • POST: リソースの作成
  • GET: リソースの取得
  • PUT: リソースの更新(全体を置き換え)
  • PATCH: リソースの更新(一部を置き換え)
  • DELETE: リソースの削除

後述のように、RequestsではHTTPメソッドの名前がそのままメソッドの名前になっている。

Qiita APIのアクセストークン取得

サイトに公開されている情報を取得するGETメソッドにはアクセストークンが必要ないものもあるが、記事を作成したり削除したりするにはアクセストークンが必要。

ログインした状態でアカウントアプリケーションから、個人用アクセストークンの「新しくトークンを発行する」をクリックし、スコープの「read_qiita」と「write_qiita」にチェックをして発行する。

アクセストークンは一度しか表示されないのでどこかにコピペしておく。分からなくなったら削除して作り直せばいい。

ここでは以下のようにテキストファイルに記入したアクセストークンを読み込んでいるが、headersとして使う{'Authorization': 'Bearer <access_token>'}という辞書(dict型オブジェクト)が生成できればどのような方法でもOK。

import requests
import pprint

with open('data/temp/qiita_access_token.txt') as f:
    qiita_access_token = f.read().strip()

headers = {'Authorization': 'Bearer {}'.format(qiita_access_token)}

なお、pprintは出力を見やすくするためにインポートしている。

POST(記事作成): requests.post()

POSTメソッドで記事を新規作成する。

requests.post()の引数jsonに作成する記事の内容を辞書で指定する。設定項目はドキュメント参照。tagsには少なくとも一つのタグを指定する必要があるので注意。

url_items = 'https://qiita.com/api/v2/items'

item_data = {
    'title': 'テスト記事',
    'body': 'テスト',
    'private': True,
    'tags': [{'name': 'test'}],
    'coediting': False,
    'gist': False,
    'tweet': False
}

r_post = requests.post(url_items, headers=headers, json=item_data)

正常に記事が作成された場合のステータスコードは201。作成された記事の情報がJSON形式で返る。

print(r_post.status_code)
# 201

pprint.pprint(r_post.json())
# {'body': 'テスト\n',
#  'coediting': False,
#  'comments_count': 0,
#  'created_at': '2018-07-12T22:05:19+09:00',
#  'group': None,
#  'id': '93ead2568150009de5f1',
#  'likes_count': 0,
#  'page_views_count': None,
#  'private': True,
#  'reactions_count': 0,
#  'rendered_body': '<p>テスト</p>\n',
#  'tags': [{'name': 'test', 'versions': []}],
#  'title': 'テスト記事',
#  'updated_at': '2018-07-12T22:05:19+09:00',
#  'url': 'https://qiita.com/nkmk/private/93ead2568150009de5f1',
#  'user': {'description': '',
#           'facebook_id': '',
#           'followees_count': 0,
#           'followers_count': 0,
#           'github_login_name': None,
#           'id': 'nkmk',
#           'items_count': 0,
#           'linkedin_id': '',
#           'location': '',
#           'name': '',
#           'organization': '',
#           'permanent_id': 53096,
#           'profile_image_url': 'https://qiita-image-store.s3.amazonaws.com/0/53096/profile-images/1473692950',
#           'twitter_screen_name': None,
#           'website_url': ''}}

例ではprivateTrueとしているので、作成した記事はマイページの限定共有投稿で確認できる。

post()の引数jsonはRequestsのバージョン2.4.2から追加された。jsonに指定することで辞書が自動的に文字列に変換され、リクエストヘッダのContent-Typeapplication/jsonに変更される。

引数dataを使う場合は、標準ライブラリのjsonモジュールをインポートした上でjson.dumps(item_data)で辞書を文字列に変換して指定する(data=json.dumps(item_data))。この場合、リクエストヘッダheadersContent-Typeapplication/jsonに指定しておく必要がある。

jsonモジュールについては以下の記事を参照。

GET(記事取得): requests.get()

POSTのResponseから作成した記事のIDを取得し、GETメソッドで該当の記事の情報を取得する。

POSTで作成した記事の内容が取得できる。

item_id = r_post.json()['id']
print(item_id)
# 93ead2568150009de5f1

r_get = requests.get(url_items + '/' + item_id, headers=headers)

print(r_get.status_code)
# 200

pprint.pprint(r_get.json())
# {'body': 'テスト\n',
#  'coediting': False,
#  'comments_count': 0,
#  'created_at': '2018-07-12T22:05:19+09:00',
#  'group': None,
#  'id': '93ead2568150009de5f1',
#  'likes_count': 0,
#  'page_views_count': 0,
#  'private': True,
#  'reactions_count': 0,
#  'rendered_body': '<p>テスト</p>\n',
#  'tags': [{'name': 'test', 'versions': []}],
#  'title': 'テスト記事',
#  'updated_at': '2018-07-12T22:05:19+09:00',
#  'url': 'https://qiita.com/nkmk/private/93ead2568150009de5f1',
#  'user': {'description': '',
#           'facebook_id': '',
#           'followees_count': 0,
#           'followers_count': 0,
#           'github_login_name': None,
#           'id': 'nkmk',
#           'items_count': 0,
#           'linkedin_id': '',
#           'location': '',
#           'name': '',
#           'organization': '',
#           'permanent_id': 53096,
#           'profile_image_url': 'https://qiita-image-store.s3.amazonaws.com/0/53096/profile-images/1473692950',
#           'twitter_screen_name': None,
#           'website_url': ''}}

取得したJSONのデータをファイルとして保存したい場合は標準ライブラリのjsonモジュールのjson.dump()を使う。

PATCH(記事更新): requests.patch()

PATCHメソッドで記事の内容を更新する。

ここではPOSTメソッドで使った記事内容の辞書の一部を変更して引数jsonに指定する。

item_data_updated = item_data.copy()
item_data_updated['title'] = 'テスト記事更新'
print(item_data_updated)
# {'title': 'テスト記事更新', 'body': 'テスト', 'private': True, 'tags': [{'name': 'test'}], 'coediting': False, 'gist': False, 'tweet': False}

r_patch = requests.patch(url_items + '/' + item_id, headers=headers, json=item_data_updated)

print(r_patch.status_code)
# 200

同じIDのまま記事の内容(ここではtitle)が更新されている。

pprint.pprint(r_patch.json())
# {'body': 'テスト\n',
#  'coediting': False,
#  'comments_count': 0,
#  'created_at': '2018-07-12T22:05:19+09:00',
#  'group': None,
#  'id': '93ead2568150009de5f1',
#  'likes_count': 0,
#  'page_views_count': None,
#  'private': True,
#  'reactions_count': 0,
#  'rendered_body': '<p>テスト</p>\n',
#  'tags': [{'name': 'test', 'versions': []}],
#  'title': 'テスト記事更新',
#  'updated_at': '2018-07-12T22:05:19+09:00',
#  'url': 'https://qiita.com/nkmk/private/93ead2568150009de5f1',
#  'user': {'description': '',
#           'facebook_id': '',
#           'followees_count': 0,
#           'followers_count': 0,
#           'github_login_name': None,
#           'id': 'nkmk',
#           'items_count': 0,
#           'linkedin_id': '',
#           'location': '',
#           'name': '',
#           'organization': '',
#           'permanent_id': 53096,
#           'profile_image_url': 'https://qiita-image-store.s3.amazonaws.com/0/53096/profile-images/1473692950',
#           'twitter_screen_name': None,
#           'website_url': ''}}

DELETE(記事削除): requests.delete()

DELETEメソッドで記事を削除する。

正常に削除された場合、ステータスコード204が返る。

r_delete = requests.delete(url_items + '/' + item_id, headers=headers)

print(r_delete.status_code)
# 204

PUT(タグフォロー): requests.put()

PUTメソッドの例として、タグをフォローする。

文字列メソッドformat()を使って、ドキュメントの通りURLにタグIDを埋め込む。

正常に処理された場合、ステータスコード204が返る。

url_tag = 'https://qiita.com/api/v2/tags/{}/following'

tag = 'python'

r_put = requests.put(url_tag.format(tag), headers=headers)

print(r_put.status_code)
# 204

フォローを外すときはDELETEメソッド。

r_delete_tag = requests.delete(url_tag.format(tag), headers=headers)

print(r_delete_tag.status_code)
# 204

関連カテゴリー

関連記事