獲取咕咚運動移動應用中的數據——Python實現


Author : iascchen(at)gmail(dot)com

Date : 2013-07-18

新浪微博 : @問天鼓


利用Python實現了咕咚 Codoon 運動的 API。對應API詳細說明參見 獲取咕咚運動移動應用中的數據——非官方API

代碼地址

https://github.com/iascchen/VisHealth/

使用 devices/codoon.py 即可。

依賴包

requests 當前使用版本爲 1.2.3

源代碼說明

codoonurl.py 爲 Codoon 服務請求 URL 入口生成工具。

codoon.py 爲 Codoon 運動非官方 API 的 Python 實現代碼。它的 main 方法是使用這些API的示例。

  1. Codoon API 被封裝在 class DeviceCodoon 中
  2. Codoon App 一般通過 HTTP 協議與 api.codoon.com 通訊。在進行其他訪問之前,必須先登錄。可以用 Codoon 網註冊用戶通過 HTTP Basic 協議進行登陸。正確登錄之後,這個 Token 將被存放爲 DeviceCodoon 實例中的 codoonHeaders 變量中,每次向服務器的請求,都需要將 codoonHeaders 的加載在 HTTP Header 中提供。Codoon App 還支持利用新浪微博、騰訊微博、人人網的用戶,通過OAuth協議登錄(這幾種登錄方式本文並未論述)。
  3. 訪問Codoon其他站,需要進行 SSO,這個SSO需要用到 Cookies, 調用 get_misc_mobile( ) 方法後,如果正確返回,包含用戶信息的 Cookies 將放在 DeviceCodoon 實例中的 codoonCookies 變量中。
  4. 如果函數調用之後,各函數會返回所收到的JSON文件。如果調用失敗,會拋出異常,或打出 Error Code 。

HTTP Basic 認證後的 HTTP Header

需要將認證時的所獲得 access_token 值設置到 HTTP Header:**Authorization** 裏,即可保持會話。除此之外,還需要將**Charset**設置爲 UTF-8。如:

Authorization : Bearer  4836c512060faa34793730959daa901f
Charset : UTF-8

帶參數的請求

需要向 Server 端提交參數的請求,需要採用 POST 方式傳參。比較特殊的是,在 Codoon 的接口中,需要將參數需要轉化爲 JSON 之後,放在 POST 體中再提交。

下面的 Python 代碼作爲參考示例:

startDate = "2013-06-01"
endDate =  "2013-06-30"
command = "http://api.codoon.com/api/gps_statistic"

request_data = {"from_date" : fromDate , "to_date" : toDate}
response = requests.post(command , data = json.dumps(request_data),  headers = self.codoonHeaders )
content = json.loads(response.content)

代碼示例

爲了方便理解,下面對原來main中的代碼進行了最簡化改寫,去掉了一些不必要的爲了輸出和驗證的代碼。


Part 1. 登陸

可以用 Codoon 網註冊用戶通過 HTTP Basic 協議進行登陸。

Codoon App 還支持利用新浪微博、騰訊微博、人人網的用戶,通過OAuth協議登錄(這幾種登錄方式本文並未論述)。

函數說明:

# 登錄
get_users_login(self , email , password )

# 獲得用戶基本信息憑證
verify_credentials(self)

參考代碼:

account = { "email" : "your@email" , "passwd" : "yourpassword" }

device = DeviceCodoon ()

# login
logined = device.get_users_login(account["email"], account["passwd"])
print device.auth_info

credentials = device.verify_credentials()

Part 2. 用戶運動成就

函數說明:

# 返回用戶的成就信息
get_user_growing_point_related(self)

# 返回用戶的運動紀
gps_highest_record(self)

# 用戶所獲得的獎章
get_user_medal(self)

# 統計信息
# 日期格式爲: yyyy-mm-dd, 如:2013-06-01
gps_statistic(self , fromDate , toDate)

參考代碼:

account = { "email" : "your@email" , "passwd" : "yourpassword" }

startDate = "2013-06-01"
endDate =  "2013-06-30"

device = DeviceCodoon ()

# login
device.get_users_login(account["email"], account["passwd"])

# records
growingPoint = device.get_user_growing_point_related( )

# 紀錄
record = device.gps_highest_record( )
# 獎章
medal = device.get_user_medal( )
# 統計
statistic = device.gps_statistic( startDate , endDate )

Part 3. 運動歷史

函數說明:

# productId 爲本機 IMEI 號,寫個假的也可以  
# count 應該是最大返回結果
# excluded 缺省值爲"", 格式不明
# page 翻頁信息
# isPart 是否返回GPS位置點記錄: 1 概述信息, 0 返回帶有GPS位置點的記錄
get_route_log(self , productId , count = 100 , excluded = "" , page = 1 , isPart = 1 )

# routeId 來自於 get_route_log 返回結果中的 "data"."route_id"
get_single_log(self , routeId)

參考代碼:

account = { "email" : "your@email" , "passwd" : "yourpassword" }

imei = "000000000000000"

device = DeviceCodoon ()

# login
device.get_users_login(account["email"], account["passwd"])

# 獲得用戶的運動歷史列表 
routes = device.get_route_log( productId = imei , isPart = 0 )

routes = device.get_route_log( productId = imei )

# 獲得具體每次的運動軌跡
for r in routes["data"]:
    routeId = r["route_id"]
    route = device.get_single_log( routeId = routeId )

Part 4. 智能配件API(疑似)

函數說明:

get_mobile_portraits(self )

get_tracker_goal(self)

# endDate 截止日期,日期格式如:2013-06-30
# daysBack 整數,向前回溯多少天。
get_tracker_summary(self, endDate, daysBack )

# datestr,日期格式如:2013-06-01
get_tracker_data(self , datestr)

# datestr,日期格式如:2013-06-01
get_sleep_data(self, datestr)

參考代碼:

account = { "email" : "your@email" , "passwd" : "yourpassword" }

endDate =  "2013-06-30"
checkDate = "2013-06-17"

device = DeviceCodoon ()

# login
device.get_users_login(account["email"], account["passwd"])

# mobile_portraits
portraits = device.get_mobile_portraits( )

# tracker_goal
tgoal = device.get_tracker_goal(  )

# tracker_summary
tsummary = device.get_tracker_summary( endDate = endDate, daysBack = 3)

# tracker_data
tdata = device.get_tracker_data( checkDate )

# sleep_data
sleep = device.get_sleep_data( checkDate )

Part 5. 其他

函數說明:

# 約跑
# point 地理位置,形式爲兩個浮點數組成的字符串。如:"36.5,112.32"
# gender 性別 : 1 Male, 0 Female. Gender is not 0 or 1, will return all
# hobby 缺省設置爲 "",返回所有結果。服務端似乎有Bug,如果 hobby 爲中文, 會返回 500 error, :(
# page 整數,頁碼 
people_surrounding(self , point , gender = 2 , hobby = None , page = 1)

# 運動計劃
# programIds 很奇葩的是被**排除在外**的 Program ID 列表,例如:如果設置爲 "3,4" ,將會返回不包括ID爲 3,4 的列表
sports_program_manifest_for_codoon(self, programIds)

# programId, 來自 sports_program_manifest_for_codoon 中的 "data"."id"
sports_program_detail(self , programId)

# 空氣質量
# cityName, 中文城市名
get_air_quality(self, cityName = None):

version_run_xml(self):

# 向 sso.codoon.com 進行認證,獲得Cookies, 如果需要訪問 www.codoon.com 的資源,就需要使用它。
def get_misc_mobile( self ):

# 訪問 http://www.codoon.com/data_v/get_user_statistic
# 得到的返回 JSON 形如: { "calorie": 82.45851, "days": 3.0, "km": 1.55822135 }
def get_user_statistic( self ):

參考代碼:

account = { "email" : "your@email" , "passwd" : "yourpassword" }

point = "36.5,112.32"

device = DeviceCodoon ()

# login
logined = device.get_users_login(account["email"], account["passwd"])

# 約跑
# Maybe Server Bug : if hobby is Chinese , server will return 500 error, :(
# ret = device.people_surrounding( point = point , gender = "1" , hobby = "跑步" , page = 1) will return 500
peoples = device.people_surrounding( point = point , gender = "1" , hobby = "") # Male

peoples = device.people_surrounding( point = point , gender = 2 , hobby = "" , page = 1) # All

# program
programs = device.sports_program_manifest_for_codoon( programIds = "3,4" ) # will return the record which ID is NOT 3 and 4

programs = device.sports_program_manifest_for_codoon( programIds = "" )

for p in programs["data"]:
    programId = p["id"]
    program = device.sports_program_detail( programId = programId )

# air quality
air = device.get_air_quality( cityName = "北京" )

# Latest App version
versionInfo = device.version_run_xml()

# access other info from codoon site
device.get_misc_mobile( )
# will return JSON such as { "calorie": 82.45851, "days": 3.0, "km": 1.55822135 }
wwwStatistic = device.get_user_statistic( ) 

祝各位玩的開心!


MD原文地址:https://github.com/iascchen/VisHealth/blob/master/docs/how-to-fetch-codoon-data-unofficial-api-python.md

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章