引言
腾讯与字节跳动作为头部互联网企业,掌握着巨大的流量资源可用于投放广告,其中腾讯广告(https://e.qq.com/ads/)是腾讯的广告投放平台,巨量引擎(https://www.oceanengine.com/)是字节跳动的广告投放平台。本分析从腾讯广告与巨量引擎这两家广告投放平台着手进行分析,目的是寻找这两家广告投放平台在广告推荐策略上的差异,其差异主要从以下几个维度进行分析:
- 用户画像数据。腾讯广告与巨量引擎各有哪些流量产品来源,能提供哪些用户画像数据;
- 投放渠道资源与展现形式。腾讯广告与巨量引擎各有哪些广告投放渠道和展现形式;
- 广告主行业。平台可以为哪些行业或实体提供投放服务;
- 投放与出价模式。平台给广告主提供了哪些广告投放模式以及出价模式;
- 成功案例分析。通过爬取腾讯广告与巨量引擎上的成功案例进行对比分析,分析两家平台广告推荐成功的案例主要集中在哪些行业,并讨论带来这些差异的可能原因;
- 总结。对腾讯广告与巨量引擎的广告推荐策略差异进行总结。
用户画像数据
腾讯广告
腾讯拥有 QQ、微信、腾讯视频、QQ 音乐、QQ 浏览器、腾讯地图等产品,涵盖社交、游戏、音视频、浏览器、地图等领域,具有覆盖面广泛的流量资源,可以获得用户较为全面的画像数据。举例来说,腾讯可根据用户的注册信息获取用户的性别、年龄、地理位置、端设备信息等基本属性,另外结合其它应用或者特定场景,如腾讯视频、QQ 音乐、腾讯新闻、腾讯游戏、京东 & 拼多多购物、微信好友 & 社群关系、微信公众号等,还能获得不同领域的兴趣画像。另外,腾讯广告平台可以根据用户与广告的交互行为数据,进一步获取用户对不同类型广告的偏好。这些数据为广告的精准投放推荐提供了能力,广告主可通过用户画像定向选择投放对象。
如图 1 所示,从腾讯广告的投放管理平台可以看到,广告投放时已开放可选的定向数据包括以下几个类别:
- 人口学属性(地理位置、年龄、性别、学历、婚育状态、工作状态、消费水平等);
- 用户行为(对教育、旅游、金融等 18 个行业类目具有行为、兴趣、意向的定向用户);
- 设备定向(品牌、上网场景、操作系统、联网方式、运营商、设备价格等);
- 流量方属性(指定广告展现在特定类型的外部媒体平台上);
- 天气定向(温度、紫外线指数、穿衣指数、化妆指数、气象)。
腾讯广告支持广告主自定义人群。值得一提的是,腾讯广告支持自动扩量,可根据广告投放积累的历史转化数据来学习除定向人群以外的其他目标人群。
巨量引擎
字节跳动拥有抖音、今日头条、西瓜视频、火山视频、懂车帝、FaceU、轻颜相机等产品,总体而言流量的覆盖面不如腾讯丰富,除了可根据用户的注册信息获取用户的性别、年龄、地理位置、端设备信息等基本属性外,可直接用于提取用户在不同领域的兴趣画像的数据能力相对有限,但值得一提的是抖音具有较丰富的用户短视频历史观看行为数据,结合短视频的标签,可以提取用户兴趣偏好相关的数据。这些数据同样为广告的精准投放推荐提供了可能性,广告主可通过用户画像定向选择投放对象。
如图 2 所示为巨量引擎的投放管理平台,可以看到广告投放时可选的定向数据包括以下几个类别:
- 人口学属性(地理位置、年龄、性别);
- 行业兴趣(可选系统推荐,或自定义选择对游戏、餐饮美食、生活服务等 20 个行业类目具有行为或兴趣的人群);
- 抖音达人(可圈定单个或某类抖音账号,并投放给与圈定账号的粉丝有相似互动行为的人群);
- 设备定向(品牌、上网场景、操作系统、联网方式、运营商、设备价格等);
- 过滤已转化用户(可选避免广告再次投放给已转化过的用户)。
值得一提的是,与腾讯广告的自动放量类似,巨量引擎支持智能放量,可逐步探索已选定向之外的人群。
对比总结
从整体来看,巨量引擎的用户画像不如腾讯广告丰富,例如在人口属性画像上腾讯广告还拥有学历、婚育状态、工作状态、消费水平等选项。结合腾讯拥有的产品及其背后的数据,腾讯广告拥有更丰富的用户画像数据,覆盖的维度也更广泛。但考虑到隐私问题,其中部分数据可能不适合直接开放给广告主使用,但是在支撑如自动扩展人群功能、广告的 ctr/cvr 预估算法模型这些黑盒功能时,腾讯广告会拥有更大的优势。关于这点我在咨询一些互联网广告业代的时候也得到了类似的结论,业代们表示在腾讯广告的定向投放效果的确相比其它广告平台会更加精准。
投放渠道资源与展现形式’
字节跳动旗下产品以信息流产品为主,在广告的展现形式上也比较趋近,多为开屏广告+信息流广告+详情页广告的组合,而腾讯的产品相对更丰富,同样有许多信息流产品。不过在广告的投放上,以微信、QQ 为核心的私密社交产品需要更多的考虑用户体验,如果广告太多可能令用户反感,因此在广告的展现形式上更加克制,没有开屏广告,这点是由业务特点导致的在广告展现形式上的差异。
广告主行业
腾讯广告支持将推广产品的行业进行分类,支持教育、旅游、金融、交通、房产、家居、服饰鞋帽箱包、餐饮美食、生活服务、商务服务、美容/个护、互联网/电子产品、体育运动、医疗健康、孕产育儿、游戏、娱乐休闲、新闻资讯这 18 个一级类目,最多可展开至三级类目,最多可选 5 个行业分类。支持自定义标签。
巨量引擎同样支持将推广产品的行业进行分类,支持3C及电器、快速消费品、食品饮料、服装配饰、医疗、商务服务、生活服务、房地产、家居建材、教育培训、出行旅游、社会公共、游戏、零售、交通工具、汽车、农林牧畜渔、化工及能源、电子电工、机械设备、文体娱乐、传媒及内容、物流业、通信、传统金融业、互联网金融、餐饮服务、工具类软件、招商加盟这 29 个一级类目,可展开至三级类目,仅支持单选行业分类。支持自定义标签,最多可添加 20 个标签。
两家平台在行业的分类体系上有不少差异,巨量引擎将行业一级类目分的更加细些。由于支持自定义标签,理论上对于合乎相关法规的广告主,两家平台都可以为其提供广告服务,只是在对行业的定义上有差异。
投放与出价模式
广告平台视角下,流量资源带来的总收益是平台关注的核心利益点。而在广告主视角下,广告带来的效果是广告主关注的核心利益点。另外,用户在不同业务场景下对于广告的价值判断存在差异,广告平台需要根据自身的业务特点,提供合适的出价模式供广告主选择,在流量资源有限的情况下,需要对广告带来的效果所转化的收益进行排序。如下图 3 所示为广告平台典型的广告推荐策略框架,除上文讨论的用户画像数据和广告展示形式的差异外,在竞价排序上两家平台同样存在一些差异,从腾讯广告投放平台可以看到其支持的出价方式包括 oCPC、oCPM、CPC、CPM。从巨量引擎广告投放平台可以看到其支持的出价方式有 oCPC、oCPM、CPA。
成功案例分析
通过爬取腾讯广告与巨量引擎的成功案例(如图 4、5),分析在这两家广告平台获得成功的广告案例主要来自哪些品牌,行业的分布是怎样的,广告主的投放目的分布是怎样的。对于腾讯广告可额外分析成功案例主要来自哪些广告投放渠道资源,以及广告主的企业规模有多大。巨量引擎可以额外分析其广告的主要展示形式有哪些。通过对比上述差异,可以一定程度上对两家广告平台的广告推荐策略差异进行一个简单的对比分析。
爬取所有数据后共得到腾讯广告成功案例100个,巨量引擎成功案例34个,数据示意图如图6,7。
在腾讯广告上获得成功的品牌包括:
后古写真 pidan 南宁古摄影 咖啡之翼 城市玩家 盘子女人坊 九荷映画 四季风 下榻小灶 尚孔教育 德雕装饰 音悦汇 米兰婚纱 可口可乐 途虎养车 惠氏 兰蔻 DW手表 斯巴鲁 比亚迪 保时捷 携程 小猪短租 招商银行 宜人贷 小猿口算 潭州教育 升学教育 叽里呱啦 喜百年 齐家 红星美凯龙 莱色婚纱 耐克 FURLA 洋河股份 唯品会 淘集集 三星手机 荣耀 京东手机 MuseMarry 茶香记 51家庭管家 全友家居 提拉米苏 唯一视觉 诺丁山 大昌行 澳华装饰 七两半 宽窄巷成都名小吃 四川航空旅行社有限公司金牛分公司 钢琴时间 大湘网 锅大侠 大连职工大学老年大学 积木家 伴鱼绘本 山东丰信农业 小罐茶 耀邦家具 中宅装饰 新物记 杭州金夫人婚纱摄影 深圳至美教育管理有限公司 竹叶青茶 壹果企画 大丰收农资商城 肯德基 太郎花子 红叶寿司 Anteprima安蒂佩玛 上海牌手表 唯一旅拍 满记甜品 交通银行 缤丽瓷砖 深圳九盛中盟影视传媒有限公司 一秒商城 彼此间商城 尚品宅配 奥格国际网球学院 世绘3Q幼少儿英语 农梦派 3K游戏 马蜂窝 易车网 轻轻家教 苏宁易购 51Talk 招商信诺人寿保险 luckin coffee 索菲亚婚纱 苏州熙兢婚纱摄影 “书单”微信公众平台 品秀音乐会所 奢邦婚纱摄影服务有限公司 亚泰集团 蛙来哒牛蛙主题餐厅
在巨量引擎上获得成功的品牌包括:
奥迪 天猫超市 得力集团 腾讯WIFI管家 MICHAEL KORS 来伊份 国际私塾 优家宝贝 装一网 老陈家豆腐脑 京致衣橱 倾国倾城婚纱摄影 唯品会 华为荣耀 高德地图 51信用卡管家 销帮帮CRM 暴风TV Uber 捕鱼大咖 有缘网 英雄联盟 标点家装网 坦克帝国 海澜之家 奇瑞捷豹路虎 养和顺堂 美团酒店 屋牛家装 江淮汽车 国美金融 光大银行 杭州奇异鸟饮品 亚谦教育咨询
如图 8 所示为腾讯广告成功案例的行业分布图,可以看到其主要分布在婚纱行业、教育行业、电商行业、家具行业、其他行业和餐饮行业。
如图 9 所示为巨量引擎成功案例的行业分布图,可以看到其主要分布在电商行业、应用软件、家居建材、汽车行业、汽车行业和招商加盟。
一个比较有趣的差异是,在腾讯广告中获得巨大成功的婚纱行业,在巨量引擎中却没有等同的效果。婚纱行业由于其行业的特殊性,对于定向人群画像的要求较高,需要定向到适龄且未有婚育的人群,而这点在人群用户画像定向的分析中已知,腾讯广告具备这样的能力来支撑这类对定向人群画像要求更高的行业实现定向人群广告推荐,而巨量引擎在这一块的能力要相对欠缺一些。
再来看腾讯广告成功案例的目标分布(如图 10),其主要分布在线索收集、线下到店和品牌推广上。
从巨量引擎的成功案例目标分布(如图 11)来看,主要分布在品牌推广、提升在线销量和应用下载上。
最后我们再来看看腾讯广告成功案例的广告投放渠道资源分布(如图 12)和广告主的规模分布(如图 13),以及巨量引擎成功案例的广告展示形式分布(如图 14)。
从腾讯广告成功案例的广告资源分布可以看到,微信广告遥遥领先,或可间接说明在微信广告上进行投放的广告更容易获得令广告主满意的效果,这点或与微信背后活跃的用户数据息息相关。另外在腾讯广告成功案例中,具有企业规模分类的案例里,从它们的企业规模分布可以看到,发展型企业占据了其中的大多数。一般而言,发展型企业在广告的投入支出上相比大型企业而言会比较有限,在广告竞价下往往不占优势,但如果能借助精准的人群画像和准确的 ctr/cvr 预估模型,使得发展型企业的广告主们能更准确地找到愿意点击或转化他们广告的用户群,在广告推荐框架的最后还是能在预估值*出价的阶段脱颖而出,从而在有限预算的情况下取得良好的广告投放效果。
最后再来看巨量引擎成功案例的广告展示形式分布,字节跳动的产品多为信息流应用,同时信息流广告也是其最主要的广告展示类型。
总结
本文尝试以广告平台的视角对腾讯广告与巨量引擎的广告推荐策略差异进行分析,从当前所了解到的广告平台在进行广告投放时所经历的各个环节入手,分析各个环节上两家广告平台的差异。整体的思路是:两家平台各有什么数据->广告可以以什么样的展现形式投放给哪些人->可以为哪些广告主提供服务->有哪些不同的投放和出价模式,在上述各个环节通过调研、与互联网广告业代交流、与平台内部同学交流等方式得出了一些主观的推测,最后再通过爬取广告平台上公开的成功案例数据,进行数据分析,希望可以得到主观推测对应的数据支撑,得出有效的结论。从整体来看,两家平台在广告展现形式、广告主行业分类定义和投放出价模式上均存在一些差异,但核心差异还是在用户画像数据和广告投放渠道资源类型上,腾讯广告在用户画像数据上的优势,是其与巨量引擎最明显的差异。
然而,受限于有限的时间,在数据支撑上依然比较单薄,但是在这个过程中,个人在互联网广告领域有了从零到一的认识,学到了非常多有趣的知识,可谓是收获满满,希望今后能有机会进一步深入互联网广告领域,钻研这一块的技术,发挥数据与算法的价值!
附 1 - 腾讯广告成功案例爬虫代码
# coding=utf-8
import pandas as pd
from requests_html import HTMLSession
# 获取所有广告卡片
def get_results(sel):
r = session.get(url)
results = r.html.find(sel)
return results
# 获取行业、目标、资源类型,用于区分广告卡片的 tag 是属于哪一类内容
def get_content(sel):
r = session.get(url)
results = []
for val in r.html.find(sel):
results.append(val.find('a')[0].text)
return results
# 获取爬取数据内容
def get_result_data(results):
data = []
for rst in results:
brand = rst.find('div.case-brand-title')[0].text
desc = rst.find('div.case-item-bd > p')[0].text
# 通过 | 分割子 tag,子 tag 前后可能有空格
desc_parse = desc.split('|')
industry = ''
target = ''
resource = ''
for i, sub_s in enumerate(desc_parse):
if sub_s.strip() in industries:
if len(industry) == 0:
industry = sub_s.strip()
else:
industry += ','
industry += sub_s.strip()
elif sub_s.strip() in targets:
if len(target) == 0:
target = sub_s.strip()
else:
target += ','
target += sub_s.strip()
elif sub_s.strip() in resources:
if len(resource) == 0:
resource = sub_s.strip()
else:
resource += ','
resource += sub_s.strip()
data.append((brand, industry, target, resource))
return data
# 保存文件
def save_file(data):
df = pd.DataFrame(data)
df.columns = ['品牌', '行业', '目标', '广告资源']
# print(df)
df.to_csv('tencent_ad_output.csv', encoding='gbk', index=False)
if __name__ == '__main__':
session = HTMLSession()
# 爬取网页 url
url = 'https://e.qq.com/success/'
# CASES
sel = '#list > div > div.case-bd.row._js_casebd > div > div > a'
results = get_results(sel)
# 行业列表
sel_industries = '#successCats > li:nth-child(1) > div > ul > li'
industries = get_content(sel_industries)
#print(industries)
# 目标列表
sel_targets = '#successCats > li:nth-child(2) > div > ul > li'
targets = get_content(sel_targets)
#print(targets)
# 资源列表
sel_resources = '#successCats > li:nth-child(3) > div > ul > li'
resources = get_content(sel_resources)
#print(resources)
data = get_result_data(results)
#print(data)
save_file(data)
附 2 - 巨量引擎成功案例爬虫代码
# coding=utf-8
import pandas as pd
from requests_html import HTMLSession
# 获取所有广告卡片
def get_results(sel):
results = r.html.find(sel)
return results
# 获取爬取数据内容
def get_result_data(results):
data = []
for rst in results:
brand = rst.find('h2')[0].text
tags = rst.find('span.tags-item')
industry = tags[0].text
target = tags[1].text
ad_type = tags[2].text if len(tags) > 2 else '未知'
data.append((brand, industry, target, ad_type))
return data
# 保存文件
def save_file(data):
df = pd.DataFrame(data)
df.columns = ['品牌', '行业', '目标', '广告资源']
#print(df)
df.to_csv('bytedance_ad_output.csv', encoding='gbk', index=False)
if __name__ == '__main__':
session = HTMLSession()
# 爬取网页 url
url = 'https://www.oceanengine.com/case'
r = session.get(url)
# 由于巨量引擎的CASE需要通过点击加载,因此通过JS模拟点击行为获取渲染后的数据
script = """
() => {
var more_button = document.querySelector("#__layout > div > div.case > div.case-content.container > div.morebtn > button")
more_button.click()
}
"""
r.html.render(script=script)
# CASES
sel = '#__layout > div > div.case > div.case-content.container > div.cases > a'
results = get_results(sel)
data = get_result_data(results)
#print(data)
save_file(data)