Python, RequestsでWeb APIを呼び出し(データ取得・操作)
PythonのHTTPライブラリであるRequestsを使ってRESTスタイルのWeb APIを呼び出しデータを取得したり操作したりする方法について説明する。
Requestsのインストールや基本的な使い方などは以下の記事を参照。
- 関連記事: Python, 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': ''}}
例ではprivate
をTrue
としているので、作成した記事はマイページの限定共有投稿で確認できる。
post()
の引数json
はRequestsのバージョン2.4.2
から追加された。json
に指定することで辞書が自動的に文字列に変換され、リクエストヘッダのContent-Type
もapplication/json
に変更される。
引数data
を使う場合は、標準ライブラリのjsonモジュールをインポートした上でjson.dumps(item_data)
で辞書を文字列に変換して指定する(data=json.dumps(item_data)
)。この場合、リクエストヘッダheaders
のContent-Type
をapplication/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()
を使う。
- 関連記事: Python, Requestsの使い方
- 関連記事: PythonでJSONファイル・文字列の読み込み・書き込み
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