当前位置: 首页 > 科技观察

李宁:携程机票前台二三事

时间:2023-03-21 22:57:16 科技观察

携程的机票跟踪点是随着业务复杂度的增加而增加的。跟踪点包括ctm、action、trace、pv、server跟踪点。在大类中,每一个埋点都符合其时代属性,但现在标准化了,它们之间存在一定的重叠。即使是多余的,有些埋点还是有价值的。转移造成的数据问题谁也不想背锅,所以埋点一直在做加法。直到app体积缩小的大势所趋,无效埋点才被部分清理掉。接下来介绍的埋点在携程的机票中有其意义,但不代表整体最好。如果是刚开始埋点的童鞋,可以参考下面各个埋点的优缺点,根据自己的需要去糟粕。取其精髓。什么是ubt?全称是UserBehaviorTrackingsystem。是由携程首席科学家叶明先生(原携程CTO)发起的一套数据框架。端app/hybrid/h5,后来加入了abtest系统,现在支持携程的很多分析项目。包括数据埋点格式、上传合约、存储、ETL和最终报表数据,是数据系统的总称。本文主要讲解ubt系统在携程埋票点的应用及指标的应用。客户端埋点客户端埋点:ctm,action,trace,pvctm埋点:玩过GA(GoogleAnalytics)的童鞋一定对utm埋点不陌生,它以get的方式记录了页面的来源,是广泛用于营销活动的收入结算,携程のutm即ctm,主要用于在线和h5平台。它不仅评估着陆页的uv,还需要根据规则计算其转化率。因为ctm只向后传递一次,不能和创建顺序直接相关(或者hybridpage被带到nativepage面临中断)。以机票专页为例,同一session的下单行为通常与当天访问过该专页的vid和sid相关联,且下单时间在页面访问时间之后,这被记录为间接订单;在此基础上,限制特价页面(截取自url)的出发城市和到达城市与订单相对应,并限制从下单到上次访问之间主页没有被再次访问特价页面(不包括正常查看特价页面后从首页主流程下单的情况),记录为直接订单。间接下单的意思是计算用户下单意愿受特价页面影响的程度,直接下单是计算从特价页面下单的情况。一般情况下,直接订单作为主要指标,间接订单作为参考指标。PV埋点:PV埋点存在时间最长,埋点方法最简单(调用logpage方法发送pageid),所以接受度最高。也作为验证新埋点丢失率的基石数据。有native/hybrid/rnapp页面实现方式,都是申请一个独立的pageid,对计算页面的性能影响不大(除了停留时间)。报表合作机制:作为基础数据,上线后第二天需要在基础报表UIP(BI域数据T+1)中找到新页面。数据流程是,在新页面上线前,开发童鞋会在公司资源平台cms上申请pageid,页面加载时调用logpage接口上传pageid。等),统计结果数据进入sqlserver,基础报表平台读取数据进行汇总展示。其中,filter字段可以通过channelid来区分工单页面。整个流程数据流转不需要人工干预,完整的流程保证了最少的人力和最快的效率。页面基础指标:在数据报表中,每个页面维度都会有UV、visits、PV、exitsnumber、pagestaytime。visits代表会话数/会话数,退出数的具体解释请自行百度。页面停留时间是本页与下一页开始时间的差值,一般取中位数(屏蔽异常值)。业务影响uv:携程机票首页区分国际国内(pageid不同)。如果用户输入“北京”->“上海”,则为国内机票首页。目的地城市为“墨尔本”时,为国际机票首页。如果用户上次购买了国内商旅机票,这次想搜索国外机票,进入时会默认记住上次国内机票的首页,所以会重新计算国内首页的uv,计算结果会高于Actualdata,所以在计算工单主流程的转化率时,以列表页为起点。动作点击/埋点:点击埋点的平台差异较大,原生埋点的格式按原生、混合、线上顺序说明:c_****,例如搜索页就是c_search,c代表click,后面是名字的英文缩写,开发者自己定义。hive表里面有个pageid字段,点击埋点。命名的时候只要保证同一个页面没有重名即可。埋点过程:app原生默认是点击按钮埋点,除非pm特别指定埋点的附加信息(比如列表页记录和屏蔽N次,但不记录屏蔽的内容。如果需要录屏的内容,需要在珠三角PM描述)。因为原生的发布周期平均为一个月,之前遇到过比较大的问题也没能及时解决。因为领导很重视,所以决定以后把所有的点击都埋起来,慢慢养成习惯。报表数据流:本报表尚未进入公司cms系统。现在前端产品在维护埋点简称和中文名称,被bi调用生成每日T+1报表。后期考虑维护进入cms系统,进入类似pv表的自动流程报表字段:点击报表是计算点击量(PV),点击用户量(UV),页面用户量(page)UV)、点击uv比(点击UV/页面UV)、人均点击(点击pv/点击UV)。虽然这个指标很简单,但是如果要跨BU或者跨公司去查数据,就需要比较计算标准。以前跟朋友查资料,因为对方埋在服务器里,根据服务请求计算pv;我们的客户端埋点,根据客户端页面刷新计算pv,导致人均pv数据明显不匹配。后来经过面对面交流,发现虽然也提到了pv,但是计算方式明显不同。混合埋点起源:2016年9月之前,混合埋点没有统一的埋点格式。不同的业务开发团队使用不同的js。经过多次推送,采用了统一的一套。因为速度是点击的名称,所以俗称“速度”埋点。报表数据流:由于速埋点都是中文的,不需要手动维护维度表,bi可以通过对结果表进行distinct生成点击过滤框。但是这需要开发不能快速添加变量字段,否则下拉列表就是一场灾难。待解决的业务问题:速度埋点包含订单信息。以混合订单详情页为例,我们可以通过orderid信息将用户在订单详情页的行为与调用行为关联起来。如果用户在订单详情页点击“退款”操作后,当天我又调用了“退款”,说明这个按钮并没有彻底解决客户的问题。此时,我们可以深入挖掘需求在快速迭代页面的过程中,注意点击每个功能后的调用比例,深入到每个页面的细节,对快速迭代和精细化数据操作很有帮助。面临的挑战:由于每次上传的内容量较大,包括系统自身的信息,如设备型号、user-agent、报错信息等,用户数据消耗较大,需要逐渐好转。在线埋点在线埋点采用了一种比较省流量的方式,即在页面离开时(包括进入下一页和刷新当前页面),将页面所有的点击信息以{点击名称:numberofclicks},可以节省流量,但是orderid等记录会丢失。如果需要更改其他信息,则有利也有弊。追溯埋点:BI分析师希望每个追溯点都能带上,从一开始就创建一个订单,这样计算转化率会更方便;但是开发认为每个页面埋点都是重复性的工作,浪费时间和精力,而且可能会丢失,影响页面加载速度。为了解决这个问题,引入了迹线埋点。这个埋点的特点是每个主流程页面只有一个,但是记录了所有的业务信息。埋点格式:每个主进程页面都有一个trace埋点,在页面加载或离开时发送,由bi统一管理。app/online/h5的格式基本相同。所有跟踪修改都需要由bi审核。主要流程页面包括首页、列表页、中间页、填写页、完成页。作用与作用:可以根据业务属性区分特定人群的行为转变,因此也被称为“业务埋点”。例如在首页选择孩子后,通过“孩子”flag,可以看到各主流程页面之间有孩子购票意愿的细分组的转化(返回首页时只能不勾选这个flag)flag会被刷新,否则会从首页带下)。这样一来,对于细分人群体验提升的效果是有目共睹的。在服务器端,机票OTA承担着航空公司的多项政策任务。它会以列表和中页标签的形式给客户不同的产品体验,但这些政策标签能带来多少销售量,又如何确定它们之间的相互关系呢?影响成为一个主题。所以从服务器端的列表页开始,记录所有的显示消息。作用:可以根据政策维度和航空公司维度筛选所有产品,通过展示转化率可以观察到每个阶段的转化情况。同时,后台相应的政策业务人员可以针对性的发送报表,一劳永逸,节省大量时间。后期会用机器学习的方法来衡量不同政策、价格、排名之间的关系,希望找到最优的转化展示方式。指标了解携程机票跟踪系统基本如上。能够清楚地了解每个跟踪点的优缺点,对于分析问题和选择数据非常有利。很多通过埋点反映出来的指标,尤其是二次计算指标,网上都有详细的定义和解释。我将讲解一下携程机票的申请和审核过程中的思考,希望能有所启发。数据关联:需要注意的是,不同的埋点有不同的缺失率。以下关联准则是笔者在科室实践中反复验证得出的,不一定具有普遍性。行为与订单的关联,以app为例,关联同一个人,行为主要是clientcode设备号,订单主要是uid,两者通过临时订单表关联(createatemporaryorderwhen填写页面创建订单),记录clientcode、uid、orderid订单号(如果拆分订单,只记录主订单),然后需要通过订单主表o_orders筛选出实际订单数据,以及最后得到每个session中的clientcode单记录和uid映射。行为-行为关联一般使用clientcode、sid、pvid来定位同一页面的行为。如果是订单号等核心数据,建议直接埋起来,不建议通过关联获取。特别是在小众群体的匹配中,基于缺失数据的关联可能会导致数据异常波动。缺失数据:现状:公司PV表存在时间最长,嵌入点最简单,结构最稳定。所有验证数据均以PV表数据为准。经验证,根据每天计算的uv数据,trace埋点准确率在97%左右,服务器埋点准确率在103%左右。如果在同类型埋点下计算转化率,分子和分母为每个页面的uvs,影响不大,但跨埋点计算时需要特别注意。量级明确后,还存在数据格式问题,尤其是string和int之间的转换,特殊字符带来的解析困难等,这些都需要在使用过程中不断验证,bi和开发一起努力。埋点的准确性受很多因素的影响,主要是双方沟通不畅造成的差距,最终体现在开发对埋点的重视不够。每个开发对埋点的理解不同,发送埋点的逻辑也不同。此外,不同的心态可能会导致结果的巨大差异。几种常见的埋点问题:不该触发的时候触发:混合页面遇到过只要手指触摸按钮就会触发埋点,导致新页面上线后点击数据异常激增。其实是开发中判断触发事件的阈值设置错误。如果停留时间超过200ms,则认为是点击,如果小于200ms,则认为是幻灯片。但是,在上面的例子中,开发没有受到限制,这就导致了问题。埋点触发相互压制:新埋点上线后,发现一个不相关的点击数据明显下降,无法从业务中查找原因。后来开发查代码的时候发现两个埋点的上传逻辑存在ifelse关系,只上传一个。不同人开发埋点导致的逻辑异常:这个主要存在于开发交接的时候。记录默认埋点的默认显示。一开始是直接由服务端发送,客户端没有过滤,所以买点的时候客户端直接读取服务端发送的内容,但是过了一段时间后,默认逻辑添加到客户端。Layer个性化界面,埋点的方式依旧是直接读取服务器内容,没有做任何改动,导致数据异常,定位问题时间较长。部门开发与框架的冲突:有时候部门开发逻辑是完整的,但是受制于框架的某些逻辑而受到指责。比如为了优化速度,在本地app打包的过程中,已经将一些文件放到了hybridpage中。混合请求时,本地会优先处理一些文件,公共框架部门做了一些拦截,但业务发展可能存在。如果不考虑这个逻辑,所有埋藏的数据都会丢失。开发对埋点的误区为什么每个页面都要埋那么多点,难道不能通过关联来实现吗?当开发本身的任务很重时,埋点就相对次要,在不理解其含义的情况下,往往意愿不强,怨声载道。这就需要pm或者bi清楚知道哪些埋点数据是必须有的,哪些是可有可无的,同时在整个项目的最终数据表现中与开发的童鞋共享数据,强化埋点的价值。另外对于开发童鞋比较关心的KPI,比如页面性能嵌入点,包括错误信息、加载时间、白屏等,可以辅助制作报表,增强对数据的关注度。为什么每次都需要增加埋点,一次就能提升?这是一个历史问题,因为在分析问题的时候,维度是在不断细化的,而这些维度是一开始没有想到的,或者说是可能的。我认为没有必要的埋点(不必要的埋点不会增加开发的工作量),但是出现问题后,需要增加埋点,这也需要和开发密切沟通。新老用户:定义:从接入维度来看,如果设备号在历史上没有访问过携程APP,则该设备是接入维度的新用户;从订单维度来看,uiv在历史上从来没有在携程app中下单成功过,那么设备就是订单维度的新用户。uv的区别:从访问维度来看,是通过设备号vid/clientcode查看;从order维度来看,是通过uid来查看的。设备平台差异:即使uid已经在网签下单,某日app首次下单,也被识别为新用户下单应用程序。辩证关系:如果一个人是在app平台下单的新用户,设备号一般是访问的新用户(一般很少有人把手机借给他人登录携程账号,因为如果帮朋友下单,可以用自己的账号下单,成为异常用户的概率比较高);如果某个设备号在某天被识别为app的新用户,则uid不一定是下单的新用户(因为不是必须要下单的,也有可能是uid买了新的)手机。)携程票是一个比较成熟的APP,新老用户比例基本保持动态平衡。Retentionrate/repurchaserevisitrate:复购率:季度复购率,机票属于低频消费品,复购率的比值经过长期观察发现季度周期更有指导意义。回访率:每月回访率。Dwelltime:定义:pvid+1后本页与下一页的开始时间之差,计算方式一般采用中位数(避免异常值影响整体性能)。会话时长计算:首次搜索->下单时间,最后一次搜索->下单时间,两个反映用户决策时间的指标,计算方式同会话。但是,机票购买决策的制定时间较长,订单从产生想法到最终下单在一个环节完成的比例较低。以后考虑在跨session的情况下计算时间,尽量接近真实停留时间。native和hybrid混合使用的停留时间:停留时间的计算是使用pvid+1页面访问时间与本页面的访问时间之差计算的(艾瑞力在线端的访问时间为duration,即意思是激活时间,实际上可以代表当前页面停留时间),如果native和embeddedhybrid(申请pageid)先后加载,填充页面的停留时间实际上变成了hybridpage-native的开始时间页面,实际加载两个页面的时间差,这个时间差不是用户真实的停留时间。停留时间是不是越短越好?(看我的回答之前最好想清楚。)对于携程机票这个电商网站来说,停留时间是辅助指标而不是决定性指标。它需要与一些决定性指标进行比较。指标一起推断用户行为。例如,填写页面的停留时间也缩短了。当填写页面后的转化率增加时,可以理解这个页面让用户安心。需要用户填写和查看的信息很少,对携程的网站也很熟悉。有信心,快速下单,这是积极的事情;而如果填写完页面后转化率下降,可能是页面上有很多冗余信息,没有找到用户想要关注的信息,或者是让用户感到反感的信息是这样的引人注目的是,它导致用户没有下单就立即离开,这成了一件棘手的事情。结合业务可能会找到很多原因,但可以肯定的是,单纯追求停留时间的增减是没有意义的。TA需要核心指标一起定位原因。行为流可视化的必要性:可以为每个用户创建一个行为流表,这样pm就可以根据uid、手机号等常用字段搜索用户的页面和点击行为流,方便发现问题,找到解决问题的灵感。因为解决问题是一个从特殊到通用的过程,可以通过行为流找到灵感,然后用SQL验证是否通用,分析能力螺旋上升的过程。在埋点新上线的测试环境中进行对比,实际看埋点的数据格式是否符合预期。附录vid/clientcode/clientid:设备标识字段,vid适用于online和h5(受浏览器和cookie限制,更换浏览器或清除cookie后vid会更新),clientcode代表app/native和hybrid(只与设备相关,在在不更换设备的情况下,标识符是唯一的)sid:sessionid,又称为sessionid,以在线为例,同一session是同一设备访问同一网站30分钟内的同一session。pvid:pv的计数,一天内同一用户的ctrip页面访问pv从1开始标记,记录该人当天访问的所有页面的顺序,按30分钟切session。starttime:事件发生时间,pv表中指页面浏览时间,action表中指按钮触发时间。UV:考虑行为时,用设备号标识,考虑订单量时,用uid标识。总结一下携程的市值从2014年的60亿增长到2016年的140亿,其中机票贡献了2016年超过40%的利润。快速增长的业务必然需要大量的数据来支撑整体的发展,而发展的问题需要通过发展来解决。整个埋葬系统其实更复杂,其中的难点不用多说。整体趋势下,我一直坚持两个原则:用户交互的埋点一般放在前端,因为客户端离用户最近,一些逻辑放在客户端,服务不一定点击后发送;而服务端则以展示为主,可以记录整个发送的消息数据,并详细分析展示转化率。当概念很复杂时,将相似的概念放在一起比较理解,防止概念混淆,比如退出率、跳出率;UV号/session号/PV号;回购率、回访率等【本文为专栏作家“李宁”原创稿件,转载请联系作者获得授权】点此阅读更多该作者好文