Foursquare上数据的获取,官方给出了很全的API(FOURSQUARE DEVELOPERS),难点在于Check-in历史的获取,需要用户验证,所以需要Foursquare授权码(code)的获取和认证Token(access_token)。
一、准备
1. Django搭建Web ,定制首页和重定向位置,具体随意。但该地址需要放在公网上,保证Foursquare能访问到。
urlpatterns = [
path('index/', views.index, name = 'index'),
path('auth/', views.auth, name = 'auth'),
path('admin/', admin.site.urls),
]
2. Foursquare上创建APP(https://developer.foursquare.com/docs/api),将第一步配置好的地址添加到Application Url和Redirect URI上。并记下Client ID和Client Secret。
二、完成验证和数据获取
结合OAuth2.0的知识,参考官方文档的四个步骤:
1. 发起请求
step_1 = 'https://foursquare.com/oauth2/authenticate?client_id=%s&client_secret=%s&response_type=code&redirect_uri=%s' % (
YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REGISTERED_REDIRECT_URI)
resp = requests.get(step_1, cookies=cs)
正常请求发起后,需要登录Foursquare账号进行手动授权。所以这里添加了cookie,cookie的具体内容可以利用浏览器的开发者工具跟踪一次授权,看一下,可以很简单的抓取到。
2. 获取Code
请求到达Foursquare后,会重定向到YOUR_REGISTERED_REDIRECT_URI,并携带授权code。
这个code每次都会不一样,可以在views auth里进行获取
def auth(request):
code = request.GET.get('code')
3. 获取token
利用获取到的code,访问Foursquare,获取token:
step_3 = 'https://foursquare.com/oauth2/access_token?client_id=%s&client_secret=%s&grant_type=authorization_code&redirect_uri=%s&code=%s' % (
YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REGISTERED_REDIRECT_URI, code)
resp = requests.get(url=step_3)
token = json.loads(resp.content)
4. 获取Check-in History
首先生成时间范围的时间戳:
# 今天日期
today = datetime.date.today()
# 明天时间
tomorrow = today + datetime.timedelta(days=1)
today_start_time = int(time.mktime(time.strptime(str(today), '%Y-%m-%d')))
today_end_time = int(time.mktime(time.strptime(str(tomorrow), '%Y-%m-%d'))) - 1
生成当前时间作为版本号:
nowTime = datetime.datetime.now().strftime('%Y%m%d') # 现在
访问API,获取最终数据:
url = 'https://api.foursquare.com/v2/users/%s/checkins?oauth_token=%s&v=%s&beforeTimestamp=%s&afterTimestamp=%s' % (YOUR_FOURSQUARE_ID,
token['access_token'], nowTime, today_end_time, today_start_time)
resp = requests.get(url=url)
data = json.loads(resp.text)
这里的YOUR_FOURSQUARE_ID是用户在Foursquare的用户ID;beforeTimestamp对应的时间点,只该时间点之前;afterTimestamp对应该时间点之后。时间范围应该是[afterTimestamp, beforeTimestamp]。
返回的data,就包含今天一天所发生的Check-in的历史数据。
4. 生成ICS文件
Python有ics包: pip install ics
from ics import Calendar, Event
c = Calendar()
while True:
url = 'https://api.foursquare.com/v2/users/self/checkins?oauth_token=%s&v=%s&beforeTimestamp=%s&afterTimestamp=%s&limit=250&&offset=%s'%(token['access_token'], nowTime, today_end_time, yesterday_start_time, offset)
resp = requests.get(url=url)
data = json.loads(resp.text)
if len(data['response']['checkins']['items']) == 0:
break
for item in data['response']['checkins']['items']:
try:
e = Event()
e.name = item['venue']['name']
e.uid = item['id']
e.begin = item['createdAt'] + item['timeZoneOffset']
e.location = '%s'%'-'.join([s for s in item['venue']['location']['formattedAddress']])
c.events.add(e)
except:
continue
offset += 250
file_path = os.path.join(settings.MEDIA_ROOT, 'HistoryCheckins', 'HistoryCheckins.ics')
[dir_name, file_name] = os.path.split(file_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
with open(file_path, 'w', encoding='utf-8') as f:
f.writelines(c)
接口限制,每次最多取250条数据,数据量大的话,可以循环读取,逐个写入到Calendar的实例中,然后直接写入到ics文件中。
5. 补充
每天定时获取,使用的django_apscheduler库。
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job
try:
# 实例化调度器
scheduler = BackgroundScheduler()
# 调度器使用DjangoJobStore()
scheduler.add_jobstore(DjangoJobStore(), "default")
# 每日凌晨执行
@register_job(scheduler, 'cron', month='*', day='*', hour='0', minute='0', second='0', id='create_history_checkins')
def create_history_checkins():
# 添加完整COOKIE,否则需要登录验证
cs = {
### ***************** ###
}
step_1 = 'https://foursquare.com/oauth2/authenticate?client_id=%s&client_secret=%s&response_type=code&redirect_uri=%s' % (
YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REGISTERED_REDIRECT_URI)
#resp =redirect(step_1)
resp = requests.get(step_1, cookies=cs)
# 监控任务
register_events(scheduler)
# 调度器开始
scheduler.start()
except Exception as e:
print(e)
# 报错则调度器停止执行
scheduler.shutdown()
数据导出就是实现普通的文件下载。
def history_checkins(request):
file_path = os.path.join(settings.MEDIA_ROOT, 'HistoryCheckins', 'HistoryCheckins.ics')
file_name = 'HistoryCheckins.ics'
response = StreamingHttpResponse(FileManager.file_iterator(file_path))
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(file_name))
return response
END