前言#
希望大家春节假期都过得愉快。我自己去了龙仁市的韩国民俗村,玩得很尽兴。每年这个时候不仅是韩国的重要节庆,也差不多是新西兰人庆祝怀唐伊日(Waitangi Day)的日子!

引子#
新西兰驻韩商会(Kiwi Chamber)会在新西兰的公共假日组织各种活动,接下来要庆祝的就是怀唐伊日。跟所有组织一样,营销和自然曝光很重要——口碑好了,大家才会一来再来。可问题是,很多组织和社群一直留不住客人,流失率高得吓人。
怎么衡量一场活动办得好不好#
活动天生就是社交场合,线下如此,线上也一样。营销对活动的成败影响很大。说到活动营销,不能只盯着事前的宣传和筹备,活动进行中和结束后的营销同样要顾到。比如参与度和满意度,就可以直接当作关键绩效指标(KPI)。
值得关注的KPI有:#
- 参与者的现场参与度
- 社交媒体参与度 - 用一个活动话题标签,就能在社交媒体上收集到大量数据,看看参与者都在怎么聊你的活动。除了标签,社交媒体还能用来衡量参与者和赞助商的互动——如果你把这作为赞助权益提供出去,就更要盯紧了。
- 单客获取成本(CPA)
- 新客与回头客的比例 - 这个指标能告诉你新老参与者的流动是否健康。人们对活动的兴趣会随时间消退,一定程度的流失对任何成功的生意来说都正常。但如果参与者几乎全是新面孔,那就说明出问题了。
我发现的问题#
在我参与的几个社群里,加上我自己跑过的活动,我发现一个共同问题:大量参与者都是第一次来。因为缺少互动、体验不佳,之后的活动他们就再也不来了。有些场子全靠源源不断的新访客才撑得下去。到底是主办方和参与者之间几乎零互动,让人扫兴?还是参与者压根没搞清这场活动是干什么的、目标是什么?
不管怎样,有一点很清楚:互动出了问题,活动的宗旨也被误解了。其次,活动进行期间完全没人去宣传组织自身的工作,等于白白错过了大把自然曝光的机会。第三,现场设备利用率太低。活动场地一般都有投影仪,嘉宾演讲时用来打字幕(한국어和英文),之后整场活动它就一直闲着。其实完全可以用点聪明的工具,把现场气氛带起来。
解决方案#
于是,为了拉近主办方和参与者的距离,我的方案是做一面照片墙:把参与者的照片收集起来投到投影仪上,让其他参与者——还有他们Instagram上的朋友——都能看到大家在活动上玩什么!
借助Instagram,那些平时就爱分享日常的用户,手机里其实早就装好了和主办方互动、反馈意见的工具,顺带还能让朋友的朋友知道Kiwi Chamber这些活动是为了什么。
所以我的目标就定下来了:写一个小Web应用,从Instagram上抓取带 #waitangikorea 标签的照片。

技术细节#
前端#
用到的工具:#
- Jquery
- HTML
- CSS3
因为只有一个页面,我就用JQuery来控制页面上DOM的内容。
为了用JQuery管理屏幕上图片的状态,我准备了一个数组,长度和照片格子的数量一致。每当一张图片显示到屏幕上,就把它的URL存进数组对应的位置。想再加一张照片时,得先确认这张图不在数组里。下面是我的代码示例。
var img_on_screen = new Array(number_of_photo_squares);
var post_index = 0;
javascript.js
while (img_on_screen.includes(post_data['img'])) {
if( post_index > post_count - 1 ) {
post_index = 0;
}
post_data = posts[post_index];
post_index = post_index + 1;
}
img_on_screen[curr_index-1] = post_data['img'];
update_img(curr_index, post_data);
}后端#
用到的工具:#
InstaLooter#
InstaLooter可以在不提供用户名和密码的情况下抓取Instagram图片。想要Instagram的图,又不想拿自己的账号信息去网上冒险,用它正合适。
选它的最大原因也在这里:跟网上其他抓取工具不一样,它根本不需要你输入用户名和密码。
scraper.py
print(insta_api)
if insta_api == 1:
subprocess.call("python -m instalooter hashtag " + hashtag +" "+ path_to_json +" -d",shell=True)Flask#
一开始选Flask是图它配置省事,只拿它来托管静态文件,结果碰上了缓存问题。客户端每次请求更新后的JSON文件,拿回来的却和上一次一模一样,用户那边的照片就对不上了。为了解决这个问题,我不再让客户端直接请求静态文件,而是在Flask上写了一个接收话题标签和图片文件名的路由。这样就能设置 cache_timeout=-1,不让文件被缓存。
文件结构#
@app.route('/update', methods= ['GET'])
def get_file():
# cache_timeout是send_file选项中的秒数
return send_from_directory("data/img", "data.json", cache_timeout=-1)Glob#
Glob很适合按规则挑文件。比如要合并多个JSON文件时,得先把每个JSON文件都读进来,才能把内容拼到一起。
scraper.py
for f in glob.glob(path_to_json+"*.json"):
with open(f, "rb") as infile:
result.append(json.load(infile))
谢谢你读到这里!#
还有什么问题的话,随时发邮件给我!
