ゴール
この記事では、Pythonを使用してStravaのAPIからアクティビティデータを取得し、そのデータを整理して出力します。
スタートライン
- Pythonの基本的な知識
- Stravaアカウント
- Strava APIのクライアントIDとクライアントシークレット(StravaのWebサイトで取得)
環境
- Windows 11
- Python 3.11.5
-
requests
ライブラリ -
python-dotenv
ライブラリ
ステップ1 環境変数の設定
今回のPythonファイルを実行するディレクトリに.envファイルを作成します。
https://www.strava.com/settings/api にアクセスし、クライアントシークレットキーを取得して、設定します。
STRAVA_TOKENは後ほど取得します。
STRAVA_CLIENT_SECRET = "<YOUR STRAVA CLIENT SECRET>"
STRAVA_TOKEN = ""
もし、StravaのAPIキー未作成の方は、以下の記事を参考に作成してみてください。
ステップ2 Strava API で認証コードを取得
token.pyを作成し、以下のコードを追加してください。
YOUR CLIENT ID部分はご自身のクライアントIDに置き換えてください。
import requests
from dotenv import load_dotenv
load_dotenv()
import os
client_id = "<YOUR CLIENT ID>"
client_secret = os.environ["STRAVA_CLIENT_SECRET"]
redirect_uri = "http://localhost/"
request_url = (
f"http://www.strava.com/oauth/authorize?client_id={client_id}"
f"&response_type=code&redirect_uri={redirect_uri}"
f"&approval_prompt=force"
f"&scope=profile:read_all,activity:read_all"
)
print("クリックしてください:", request_url)
print("アプリを認証し、生成されたコードを以下のURLにコピー&ペーストしてください。")
code = input("URLからコードを貼り付ける: ")
このコードは、ユーザーがStravaの認証ページにアクセスし、アプリケーションに必要な権限を与えるためのURLを生成します。ユーザーが認証を完了すると、リダイレクトURIに認証コードが付与されます。このコードは次のステップでアクセストークンを取得するために使用されます。
ステップ3 アクセストークンを取得
token.pyに以下のコードを追加します。
token = requests.post(
url="https://www.strava.com/api/v3/oauth/token",
data={
"client_id": client_id,
"client_secret": client_secret,
"code": code,
"grant_type": "authorization_code",
},
)
strava_token = token.json()
print(".envにアクセストークンを追加する", strava_token["access_token"])
このステップでは、先ほどの認証コードを使用してStrava APIからアクセストークンを取得します。このトークンは、APIリクエストを認証するために必要です。
ステップ4 token.pyの実行
token.pyを実行します。
クリックしてください: http://www.strava.com/oauth/authorize?client_id=53395&response_type=code&redirect_uri=http://localhost/&approval_prompt=force&scope=profile:read_all,activity:read_all
アプリを認証し、生成されたコードを以下のURLにコピー&ペーストしてください。
URLからコードを貼り付ける:
「クリックしてください」のURLをクリックすると、以下のような画面が表示されるので、「許可する」を選択します。
リダイレクト先のURLのcode部分をコピーします。
以下の画像の赤で塗りつぶされた四角の部分です。
コピーしたコードを先ほどのターミナル上で貼り付けるとアクセストークンが発行されます。
クリックしてください: http://www.strava.com/oauth/authorize?client_id=53395&response_type=code&redirect_uri=http://localhost/&approval_prompt=force&scope=profile:read_all,activity:read_all
アプリを認証し、生成されたコードを以下のURLにコピー&ペーストしてください。
URLからコードを貼り付ける: [先ほどコピーしたコードを貼り付ける]
.envにアクセストークンを追加する [アクセストークン]
発行されたアクセストークンを.envファイルに指定します。
STRAVA_CLIENT_SECRET = "<YOUR STRAVA CLIENT SECRET>"
STRAVA_TOKEN = "<YOUR STRAVA TOKEN>"
ステップ5 アクティビティデータを取得して整理
activity.pyを作成し、以下のコードを追加してください。
import os
import requests
from dotenv import load_dotenv
load_dotenv()
import requests
import json
url = "https://www.strava.com/api/v3/athlete/activities"
access_token = os.environ["STRAVA_TOKEN"]
headers = {"Authorization": f"Bearer {access_token}"}
response = requests.get(url, headers=headers)
activities = response.json()
activities_list = []
for activity in activities:
activity_info = {
"id": activity.get("id"),
"name": activity.get("name"),
"distance": activity.get("distance"),
"moving_time": activity.get("moving_time"),
"elapsed_time": activity.get("elapsed_time"),
"total_elevation_gain": activity.get("total_elevation_gain"),
"type": activity.get("type"),
"start_date": activity.get("start_date"),
"start_date_local": activity.get("start_date_local"),
"timezone": activity.get("timezone"),
"utc_offset": activity.get("utc_offset"),
"average_speed": activity.get("average_speed"),
"max_speed": activity.get("max_speed"),
"average_cadence": activity.get("average_cadence"),
"average_temp": activity.get("average_temp"),
"average_heartrate": activity.get("average_heartrate"),
"max_heartrate": activity.get("max_heartrate"),
}
activities_list.append(activity_info)
print(json.dumps(activities_list, indent=4))
このコードでは、Strava APIを使用してアクティビティデータを取得し、そのデータを整理してリストに格納しています。取得したデータはJSON形式で出力されます。
ステップ6 activity.pyの実行
activity.pyを実行します。
最新のアクティビティがjson形式で30件取得できます。
[
{
"id": 10386737564,
"name": "Lunch Run",
"distance": 2199.1,
"moving_time": 609,
"elapsed_time": 1285,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-16T02:05:25Z",
"start_date_local": "2023-12-16T11:05:25Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.611,
"max_speed": 6.258,
"average_cadence": 87.6,
"average_temp": 19,
"average_heartrate": 131.5,
"max_heartrate": 155.0
},
{
"id": 10386565542,
"name": "Morning Run",
"distance": 1381.5,
"moving_time": 393,
"elapsed_time": 872,
"total_elevation_gain": 6.0,
"type": "Run",
"start_date": "2023-12-16T01:02:07Z",
"start_date_local": "2023-12-16T10:02:07Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.515,
"max_speed": 5.812,
"average_cadence": 86.9,
"average_temp": 18,
"average_heartrate": 131.0,
"max_heartrate": 155.0
},
{
"id": 10386453730,
"name": "Morning Run",
"distance": 1546.5,
"moving_time": 521,
"elapsed_time": 521,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-16T00:25:05Z",
"start_date_local": "2023-12-16T09:25:05Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 2.968,
"max_speed": 3.964,
"average_cadence": 85.7,
"average_temp": 21,
"average_heartrate": 131.1,
"max_heartrate": 146.0
},
{
"id": 10381558391,
"name": "Morning Run",
"distance": 12006.7,
"moving_time": 4044,
"elapsed_time": 4044,
"total_elevation_gain": 15.0,
"type": "Run",
"start_date": "2023-12-14T21:42:50Z",
"start_date_local": "2023-12-15T06:42:50Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 2.969,
"max_speed": 3.984,
"average_cadence": 85.2,
"average_temp": 21,
"average_heartrate": 137.2,
"max_heartrate": 153.0
},
{
"id": 10376442702,
"name": "Morning Run",
"distance": 3724.0,
"moving_time": 1258,
"elapsed_time": 1258,
"total_elevation_gain": 12.0,
"type": "Run",
"start_date": "2023-12-13T22:34:25Z",
"start_date_local": "2023-12-14T07:34:25Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 2.96,
"max_speed": 3.668,
"average_cadence": 85.4,
"average_temp": 13,
"average_heartrate": 149.8,
"max_heartrate": 158.0
},
{
"id": 10376440203,
"name": "Morning Run",
"distance": 6748.9,
"moving_time": 2059,
"elapsed_time": 2068,
"total_elevation_gain": 6.0,
"type": "Run",
"start_date": "2023-12-13T21:45:50Z",
"start_date_local": "2023-12-14T06:45:50Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.278,
"max_speed": 3.852,
"average_cadence": 86.0,
"average_temp": 17,
"average_heartrate": 135.8,
"max_heartrate": 153.0
},
{
"id": 10373471072,
"name": "Evening Run",
"distance": 2017.4,
"moving_time": 708,
"elapsed_time": 708,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-13T11:44:42Z",
"start_date_local": "2023-12-13T20:44:42Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 2.849,
"max_speed": 3.62,
"average_cadence": 86.2,
"average_temp": 14,
"average_heartrate": 135.1,
"max_heartrate": 147.0
},
{
"id": 10373348485,
"name": "Evening Run",
"distance": 7333.3,
"moving_time": 1557,
"elapsed_time": 1573,
"total_elevation_gain": 1.0,
"type": "Run",
"start_date": "2023-12-13T11:03:02Z",
"start_date_local": "2023-12-13T20:03:02Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 4.71,
"max_speed": 6.322,
"average_cadence": 88.0,
"average_temp": 15,
"average_heartrate": 144.8,
"max_heartrate": 158.0
},
{
"id": 10373163073,
"name": "Evening Run",
"distance": 2037.5,
"moving_time": 601,
"elapsed_time": 601,
"total_elevation_gain": 2.0,
"type": "Run",
"start_date": "2023-12-13T10:39:46Z",
"start_date_local": "2023-12-13T19:39:46Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.39,
"max_speed": 4.348,
"average_cadence": 85.6,
"average_temp": 17,
"average_heartrate": 136.8,
"max_heartrate": 151.0
},
{
"id": 10361039846,
"name": "Morning Run",
"distance": 10276.5,
"moving_time": 2774,
"elapsed_time": 2777,
"total_elevation_gain": 14.0,
"type": "Run",
"start_date": "2023-12-10T22:10:39Z",
"start_date_local": "2023-12-11T07:10:39Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.705,
"max_speed": 4.376,
"average_cadence": 84.8,
"average_temp": 19,
"average_heartrate": 148.2,
"max_heartrate": 173.0
},
{
"id": 10356566613,
"name": "Afternoon Run",
"distance": 11805.8,
"moving_time": 3671,
"elapsed_time": 3672,
"total_elevation_gain": 14.0,
"type": "Run",
"start_date": "2023-12-10T07:37:23Z",
"start_date_local": "2023-12-10T16:37:23Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.216,
"max_speed": 4.0,
"average_cadence": 84.5,
"average_temp": 21,
"average_heartrate": 138.1,
"max_heartrate": 150.0
},
{
"id": 10351174510,
"name": "Afternoon Run",
"distance": 3269.9,
"moving_time": 1260,
"elapsed_time": 1260,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-09T07:05:05Z",
"start_date_local": "2023-12-09T16:05:05Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 2.595,
"max_speed": 3.274,
"average_cadence": 85.6,
"average_temp": 25,
"average_heartrate": 137.7,
"max_heartrate": 151.0
},
{
"id": 10351088686,
"name": "Afternoon Run",
"distance": 5117.2,
"moving_time": 1051,
"elapsed_time": 1051,
"total_elevation_gain": 1.0,
"type": "Run",
"start_date": "2023-12-09T06:23:03Z",
"start_date_local": "2023-12-09T15:23:03Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 4.869,
"max_speed": 5.988,
"average_cadence": 91.4,
"average_temp": 25,
"average_heartrate": 192.2,
"max_heartrate": 200.0
},
{
"id": 10350990778,
"name": "Afternoon Run",
"distance": 205.0,
"moving_time": 40,
"elapsed_time": 40,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-09T05:37:36Z",
"start_date_local": "2023-12-09T14:37:36Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 5.126,
"max_speed": 5.472,
"average_cadence": 92.4,
"average_temp": 23,
"average_heartrate": 129.0,
"max_heartrate": 152.0
},
{
"id": 10350990633,
"name": "Afternoon Run",
"distance": 204.6,
"moving_time": 40,
"elapsed_time": 40,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-09T05:36:24Z",
"start_date_local": "2023-12-09T14:36:24Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 5.116,
"max_speed": 5.478,
"average_cadence": 91.8,
"average_temp": 24,
"average_heartrate": 114.4,
"max_heartrate": 128.0
},
{
"id": 10350990467,
"name": "Afternoon Run",
"distance": 1800.5,
"moving_time": 461,
"elapsed_time": 461,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-09T05:26:08Z",
"start_date_local": "2023-12-09T14:26:08Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.906,
"max_speed": 4.546,
"average_cadence": 85.7,
"average_temp": 24,
"average_heartrate": 164.9,
"max_heartrate": 181.0
},
{
"id": 10345232017,
"name": "Morning Run",
"distance": 10474.2,
"moving_time": 3182,
"elapsed_time": 3182,
"total_elevation_gain": 5.0,
"type": "Run",
"start_date": "2023-12-07T21:45:02Z",
"start_date_local": "2023-12-08T06:45:02Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.292,
"max_speed": 3.878,
"average_cadence": 86.5,
"average_temp": 11,
"average_heartrate": 143.1,
"max_heartrate": 156.0
},
{
"id": 10340205704,
"name": "Morning Run",
"distance": 11807.3,
"moving_time": 3645,
"elapsed_time": 3645,
"total_elevation_gain": 12.0,
"type": "Run",
"start_date": "2023-12-06T21:39:21Z",
"start_date_local": "2023-12-07T06:39:21Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.239,
"max_speed": 4.158,
"average_cadence": 85.5,
"average_temp": 16,
"average_heartrate": 141.2,
"max_heartrate": 156.0
},
{
"id": 10337091503,
"name": "Evening Run",
"distance": 1255.5,
"moving_time": 480,
"elapsed_time": 480,
"total_elevation_gain": 1.0,
"type": "Run",
"start_date": "2023-12-06T11:37:08Z",
"start_date_local": "2023-12-06T20:37:08Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 2.616,
"max_speed": 3.314,
"average_cadence": 85.0,
"average_temp": 16,
"average_heartrate": 148.4,
"max_heartrate": 158.0
},
{
"id": 10337012170,
"name": "Evening Run",
"distance": 4534.9,
"moving_time": 972,
"elapsed_time": 972,
"total_elevation_gain": 1.0,
"type": "Run",
"start_date": "2023-12-06T11:07:27Z",
"start_date_local": "2023-12-06T20:07:27Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 4.665,
"max_speed": 6.15,
"average_cadence": 89.4,
"average_temp": 17,
"average_heartrate": 152.5,
"max_heartrate": 166.0
},
{
"id": 10336830661,
"name": "Evening Run",
"distance": 2344.2,
"moving_time": 645,
"elapsed_time": 645,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-06T10:40:08Z",
"start_date_local": "2023-12-06T19:40:08Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.634,
"max_speed": 4.744,
"average_cadence": 86.6,
"average_temp": 23,
"average_heartrate": 137.4,
"max_heartrate": 153.0
},
{
"id": 10324615724,
"name": "Morning Run",
"distance": 15072.0,
"moving_time": 4510,
"elapsed_time": 4510,
"total_elevation_gain": 15.0,
"type": "Run",
"start_date": "2023-12-03T21:36:21Z",
"start_date_local": "2023-12-04T06:36:21Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.342,
"max_speed": 4.046,
"average_cadence": 88.2,
"average_temp": 11,
"average_heartrate": 142.6,
"max_heartrate": 156.0
},
{
"id": 10319301286,
"name": "Morning Run",
"distance": 1696.9,
"moving_time": 314,
"elapsed_time": 314,
"total_elevation_gain": 14.0,
"type": "Run",
"start_date": "2023-12-03T01:19:46Z",
"start_date_local": "2023-12-03T10:19:46Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 5.404,
"max_speed": 6.326,
"average_cadence": 93.9,
"average_temp": 22,
"average_heartrate": 141.8,
"max_heartrate": 159.0
},
{
"id": 10319174762,
"name": "Morning Run",
"distance": 171.4,
"moving_time": 30,
"elapsed_time": 30,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-03T00:50:27Z",
"start_date_local": "2023-12-03T09:50:27Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 5.714,
"max_speed": 5.972,
"average_cadence": 99.6,
"average_temp": 17,
"average_heartrate": 100.7,
"max_heartrate": 111.0
},
{
"id": 10319174531,
"name": "Morning Run",
"distance": 153.4,
"moving_time": 25,
"elapsed_time": 25,
"total_elevation_gain": 0.0,
"type": "Run",
"start_date": "2023-12-03T00:49:03Z",
"start_date_local": "2023-12-03T09:49:03Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 6.134,
"max_speed": 6.672,
"average_cadence": 104.7,
"average_temp": 18,
"average_heartrate": 76.9,
"max_heartrate": 90.0
},
{
"id": 10319174185,
"name": "Morning Run",
"distance": 3546.4,
"moving_time": 900,
"elapsed_time": 900,
"total_elevation_gain": 14.0,
"type": "Run",
"start_date": "2023-12-03T00:30:23Z",
"start_date_local": "2023-12-03T09:30:23Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.94,
"max_speed": 4.91,
"average_cadence": 86.0,
"average_temp": 18,
"average_heartrate": 147.4,
"max_heartrate": 162.0
},
{
"id": 10314570922,
"name": "Afternoon Run",
"distance": 8519.3,
"moving_time": 2820,
"elapsed_time": 2820,
"total_elevation_gain": 43.0,
"type": "Run",
"start_date": "2023-12-02T07:39:14Z",
"start_date_local": "2023-12-02T16:39:14Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.021,
"max_speed": 4.032,
"average_cadence": 85.7,
"average_temp": 17,
"average_heartrate": 149.9,
"max_heartrate": 174.0
},
{
"id": 10313577291,
"name": "Morning Run",
"distance": 8317.3,
"moving_time": 2589,
"elapsed_time": 2589,
"total_elevation_gain": 42.0,
"type": "Run",
"start_date": "2023-12-01T23:31:54Z",
"start_date_local": "2023-12-02T08:31:54Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.213,
"max_speed": 4.238,
"average_cadence": 85.9,
"average_temp": 15,
"average_heartrate": 146.2,
"max_heartrate": 167.0
},
{
"id": 10308646155,
"name": "Morning Run",
"distance": 15070.7,
"moving_time": 4511,
"elapsed_time": 4511,
"total_elevation_gain": 16.0,
"type": "Run",
"start_date": "2023-11-30T21:36:50Z",
"start_date_local": "2023-12-01T06:36:50Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.341,
"max_speed": 4.054,
"average_cadence": 86.6,
"average_temp": 15,
"average_heartrate": 145.4,
"max_heartrate": 160.0
},
{
"id": 10303511405,
"name": "Morning Run",
"distance": 15049.8,
"moving_time": 4591,
"elapsed_time": 4597,
"total_elevation_gain": 16.0,
"type": "Run",
"start_date": "2023-11-29T21:39:00Z",
"start_date_local": "2023-11-30T06:39:00Z",
"timezone": "(GMT+09:00) Asia/Tokyo",
"utc_offset": 32400.0,
"average_speed": 3.278,
"max_speed": 4.19,
"average_cadence": 86.3,
"average_temp": 15,
"average_heartrate": 134.2,
"max_heartrate": 161.0
}
]
フィニッシュ
お疲れ様でした!
以下のXアカウントでも情報発信を行っていますので、ぜひフォローしてください!
参考文献