Apple ヘルスケアアプリのexport.xmlを使って指定時間範囲の歩数を集計  Python


Appleのヘルスケアアプリからエクスポートしたデータ(`export.xml`)を解析し、**指定時刻から過去〇時間分の歩数データを抽出して合計する方法**を解説します。さらに、事前にデバイス名を確認し、対象デバイスを選択する手順を組み入れました。

---

## やりたいこと
1. **指定した終了時刻**（例: 2024年12月2日 午前0時）から**過去24時間分のデータ**を抽出。
2. デバイス名（`sourceName`）を事前に確認し、集計対象とするデバイスを選択。
3. その歩数データを合計して表示。

---

## 必要な準備
1. Appleヘルスケアアプリからデータをエクスポートします（[手順はこちら](https://www.apple.com/jp/legal/privacy/data/ja/health-app/#:~:text=%E3%83%98%E3%83%AB%E3%82%B9%E3%82%B1%E3%82%A2%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E3%81%AF%E3%80%81%E3%81%8A,%E6%9B%B8%E3%81%8D%E5%87%BA%E3%81%99%E2%80%9D%E3%82%92%E3%82%BF%E3%83%83%E3%83%97%E3%81%97%E3%81%BE%E3%81%99%E3%80%82&text=%E3%83%98%E3%83%AB%E3%82%B9%E3%82%B1%E3%82%A2%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92iCloud%E3%81%AB%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)）。
2. 解凍したZIPファイル内の `export.xml` を準備します。

---

## コード

以下のコードを実行すると、指定時刻から過去〇時間分の歩数データを抽出・合計します。

```python
import xml.etree.ElementTree as ET
from datetime import datetime, timedelta, timezone

# 【1】設定：指定時刻と時間範囲
specified_time_str = '2024-12-02 00:00:00'  # 終了時刻（例: 2024年12月2日 午前0時）
hours_range = 24  # 過去〇時間分を抽出（例: 24時間）
specified_time = datetime.strptime(specified_time_str, '%Y-%m-%d %H:%M:%S').replace(
    tzinfo=timezone(timedelta(hours=9)))  # 日本時間に変換
start_time = specified_time - timedelta(hours=hours_range)

# 【2】XMLファイルのパス（エクスポートファイルを指定）
xml_file_path = '/path/to/export.xml'

# 【3】XMLデータをパース
tree = ET.parse(xml_file_path)
root = tree.getroot()

# 【4】デバイス名（sourceName）の一覧を表示
source_names = {record.attrib.get("sourceName") for record in root.findall("Record") if record.attrib.get("type") == "HKQuantityTypeIdentifierStepCount"}
print("利用可能なデバイス名 (sourceName):")
for name in source_names:
    print(name)

# ユーザーにデバイス名を指定してもらう
device_name = input("対象とするデバイス名を入力してください: ")

# 【5】指定条件で歩数データを絞り込み
step_count_records = [
    record.attrib for record in root.findall("Record")
    if record.attrib.get("type") == "HKQuantityTypeIdentifierStepCount" and
       record.attrib.get("sourceName") == device_name and
       start_time <= datetime.strptime(record.attrib['startDate'], '%Y-%m-%d %H:%M:%S %z') <= specified_time
]

# 【6】歩数データを合計
total_steps = sum(int(record['value']) for record in step_count_records)

# 【7】結果を表示
print(f"指定時刻: {specified_time_str}")
print(f"過去{hours_range}時間分の歩数データ: {len(step_count_records)}件")
print(f"合計歩数: {total_steps}")
```

---

## 実行手順

1. コードを実行すると、`sourceName`（デバイス名）の一覧が出力されます。
   ```plaintext
   利用可能なデバイス名 (sourceName):
   John's iPhone
   John's Apple Watch
   ```

2. 集計したいデバイス名を入力します（例: `"John's Apple Watch"`）。
   ```plaintext
   対象とするデバイス名を入力してください: John's Apple Watch
   ```

3. 結果が表示されます。
   ```plaintext
   指定時刻: 2024-12-02 00:00:00
   過去24時間分の歩数データ: 15件
   合計歩数: 6200
   ```

---

## コードのポイント

### 1. デバイス名の一覧を表示
以下の部分で、XML内に存在するすべての`sourceName`（デバイス名）を抽出して表示します。
```python
source_names = {record.attrib.get("sourceName") for record in root.findall("Record") if record.attrib.get("type") == "HKQuantityTypeIdentifierStepCount"}
print("利用可能なデバイス名 (sourceName):")
for name in source_names:
    print(name)
```

### 2. ユーザーがデバイス名を指定
ユーザーに手動でデバイス名を入力してもらい、条件に反映させます。
```python
device_name = input("対象とするデバイス名を入力してください: ")
```

### 3. 時間範囲のデータを抽出
`startDate` が指定した範囲に収まるデータを抽出します。
```python
start_time <= datetime.strptime(record.attrib['startDate'], '%Y-%m-%d %H:%M:%S %z') <= specified_time
```

---

## 注意点
- **デバイス名は正確に入力**  
  `sourceName` を正確に入力しないとデータが抽出されません。
- **ファイルパスの指定**  
  `xml_file_path` を正しいパスに設定してください。
- **大規模データの処理**  
  大量のデータを扱う場合、メモリ使用量に注意が必要です。

---

## まとめ

このコードを使えば、**指定時刻から過去〇時間分**の歩数データを簡単に抽出し、特定デバイスに絞り込んで合計できます。  
デバイス選択のフェーズを取り入れることで、柔軟にデータを解析できるようになります。ぜひお試しください！