Facebook应用开发-之获取直播视频分析数据

业务场景

	1.我的业务场景:
		 	从Facebook平台,获取直播视频分析数据(用于数据统计)
	
	2.适用的业务场景:
			 Facebook开发平台第三方应用开发
			 Puppeteer爬取Facebook/其他网页数据
	

技术方案

1. 应用接口获取: 在facebook开发平台注册facebook应用,使用接口获取数据
2. excel数据导入: 在facebook的视频分析主页中,导出视频分析数据,再使用PHPExcel导入数据库
3. 爬虫扒取网页:puppeteer登陆facebook后,模拟用户界面操作,读取dom元素,获取相关视频数据

说明

	1. 以下facebook均简称为 fb
	2. page_id 实际是视频主播在fb平台的唯一ID标识 (即主页和主播是一一对应的)
	3. 因为三种方案分别涉及不同的技术工具,牵扯的代码片段和细节较多,为了不影响读者了解本次逻辑流程,我会另外写三篇博客来介绍各自的技术工具,以及相关细节和demo
	4. 欢迎提出不同见解,有遗漏之处还望指出,谢谢

第一种方案: 应用接口获取

1.涉及工具: 
	1) facebooke开发应用平台
	
2. 逻辑流程(操作步骤):
	1) 注册/设置开发者应用 =>
	2) 下载fb-PHP-SDK => 
	3) 手动获取所有主播的page_id =>
	4) 接口获取page信息(根据page_id)+视频ID列表(过滤留下直播视频ID列表) =>
	5) 接口获取video分析数据(根据video_id)

3. 涉及的接口
	1) 获取page信息接口(page_id为必填参数)
		A) 接口信息如图所示:
		![在这里插入图片描述](https://img-blog.csdnimg.cn/20190616191546572.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2R1cmluZ25vbmU=,size_16,color_FFFFFF,t_70)
		B)代码片段:
			 /**
		     * 获取主页信息
		     * @param string $pageId 主页ID
		     * @param int $monthAgo 几个月前,默认2个月
		     * @param int $endTime 某个时间的时间戳
		     */
		    public function getFBPageInfo($pageId , $monthAgo = 2, $endTime = null) {
		               $this->fb = new Facebook\Facebook([
				            'app_id' => '应用ID',	// 应用ID
				            'app_secret' => '应用secret',	//应用secret
				            'default_graph_version' => 'v3.2',	// 应用版本号,我使用的是v3.2
				        ]);
		            # 默认获取当天-前两个月的数据
		            $currDay = strtotime(date('Y-m-d 00:00:00'));
		            $untilTime = !empty($endTime) && $endTime < $currDay  ? $endTime : $currDay; //指定时间戳|当天凌晨
		            $sinceTime = strtotime("-$monthAgo month", $untilTime); //2个月前的(指定日期|今天)凌晨
		            //$queryStr = '1349433135167312?fields=name,global_brand_page_name,fan_count,category,id,verification_status,videos.since(1555806977).until(1556460756).limit(100){length,id,title,content_category,created_time,updated_time,live_status}';  //20190421-20190428
		            $queryStr = $pageId .'?fields=name,global_brand_page_name,fan_count,category,id,verification_status,videos.since('.$sinceTime.').until('.$untilTime.').limit(100){length,id,title,content_category,created_time,updated_time,live_status}';  // 获取指定时间内的主页信息+video_id列表
		            $response = $this->fb->get($queryStr, self::$fbAccessToken);
		            $data = $response->getDecodedBody();
		            return $data;
		    }
	2) 获取视频详情接口(video_id为必填参数)
		A) 接口信息如图所示:
		![在这里插入图片描述](https://img-blog.csdnimg.cn/20190616192032650.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2R1cmluZ25vbmU=,size_16,color_FFFFFF,t_70)
	B) 代码片段:
		/**
	     * 获取单个视频分析数据
	     * @param string $videoId 视频ID
	     */
		public function getFBVideoAnalysisData($videoId) {
	            # 获取视频详情信息(视频简介+分析数据)
	            $this->fb = new Facebook\Facebook([
		            'app_id' => '应用ID',	// 应用ID
		            'app_secret' => '应用secret',	//应用secret
		            'default_graph_version' => 'v3.2',	// 应用版本号,我使用的是v3.2
		        ]);
	            $queryStr = $videoId . '/?fields=id,length,live_status,picture,created_time,updated_time,title,content_category,video_insights{id,name,title,values}';
	            $response = $this->fb->get($queryStr, self::$fbAccessToken);
	            $data = $response->getDecodedBody();
	            return $data;
	    }
3.遇到的问题&解决方案:
1) 问题一: 如果筛选出直播视频
	答: 使用 获取主页信息中的video列表中的live_status字段值进行区分,live_status="VOD"的为直播视频
2) 问题二: 如何获取指定时间范围内容的视频列表
	答:fb早期是支持FQL写法的,FQL类似SQL语法的一种fb查询语句,直接通过fb接口请求FQL字符串,就可以获取查询结果,但是fb现在已经不支持FQL语法格式; 但是根据技术直觉+不断调试,发现还有有迹可循的,比如上述获取主页信息接口的截图中使用的语句就是:  //$queryStr = '1349433135167312?fields=name,global_brand_page_name,fan_count,category,id,verification_status,videos.since(1555806977).until(1556460756).limit(100); 其中page_id=1349433135167312,since表示查询起始时间,until表示查询截止时间,均为时间戳格式,limit(100),表示获取查询结果的前100条数据
	
3)问题三: 如何实时验证fb用户登录状态
	答: 因为使用的是fb的Graph-SDK(图谱API),所以直接调用获取用户信息接口即可,若登录态未失效,则返回用户信息,否则抛出异常信息: "Invalid OAuth access token."(返回该SDK中,所有请求都需要先验证access_token,而access_token生产过程:是在用户授权登录,并且登录成功后,返回的一次性code和status作为请求参数,去请求fb接口生成的access_token),因此token失效等同于用户登录态失效
4)问题四: 如何获取提高开发应用的接口使用频率上限 
	答:应用接口调用频率为 (200*应用用户数量)/小时,例如我的应用有三个用户,则接口调用频率为600次/小时,这个600次是应用在一个小时之内的所有用户接口总调用次数,可以是用户A 调用599次,用户B调用1次,用户C 调用0 次,而非每个用户200次;
5)问题五:如何获取用户信息和直播视频信息,需要哪些权限授权
	答:因为是内部使用,所以我没有经过审核,但是审核流程并不复杂,只需要使用接口将数据导入到数据库,并展示在应用网页中,即可提交审核,但务必保证是真实数据,不要使用自己造的假数据;详情见官方文档; 若是允许公开对外部可见的话,建议细分一下权限,一来公开需要审核权限,二来可以最大程度提高用户体验![在这里插入图片描述](https://img-blog.csdnimg.cn/20190616202215503.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2R1cmluZ25vbmU=,size_16,color_FFFFFF,t_70) 
6) 问题六:用户登录开发应用的前提条件
	答:
	 有两种情况:
		A)情况一:
			 应用已通过fb审核,对所有fb用户可见,fb用户只需使用fb账号进行授权登录即可
		B)情况二:
			 应用未通过权限审核,仅对部分用户可见; 首先必须在应用配置中添加访问用户,然后这些访问用户,使用fb账号进行登录应用即可
		C)二者相同点:
			 无论是否通过审核,用户都必须使用fb第三方登录,进行fb用户授权(基于Auth2.0第三方授权机制)
		D)注意:因为是内部使用,所以我没有经过审核,但是审核流程并不复杂,只需要使用接口将数据导入到数据库,并展示在应用网页中,即可提交审核,但务必保证是真实数据,不要使用自己造的假数据;详情见官方文档, 
7)问题七:调试工具使用及注意事项 
	答:
		调试工具链接: https://developers.facebook.com/tools/explorer/
		A)注意事项: 调试工具必须要先进行授权,用到哪些权限就进行相关授权,为了方便,我是授权所有权限,有兴趣的同步可参照官方文档进行细分
		B) 调试工具调用接口后,可以保存调用记录,可以得到一个会话ID: session_id,若有问题,可以去官方平台进行bug上报,并附上session_id
		C) 使用如图所示:
			![在这里插入图片描述](https://img-blog.csdnimg.cn/20190616202226496.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2R1cmluZ25vbmU=,size_16,color_FFFFFF,t_70)
	
4.注意事项:
	1) 因fb视频内容版权限制,接口获取到的视频ID不全,
	2) 视频部分参数随时间增长而增长,需要定时更新,
	3) fb应用/接口所有操作均依赖用户授权,即只有在用户登录时/接口token有效时,才能同步/更新fb数据到本地
	4) 注意应用配置问题,***因为涉及的内容和细节较多,应用配置和sdk使用细节会单独写一篇博客描述,这篇博客主要以逻辑描述为主,具体操作请见后续博客

5.小结:
	1) 优点: 客户端操作简单;
	2) 缺点: 涉及版本的视频数据无法获取,导致数据不全 [这涉及到fb的隐私版权限制,经和fb工作人员沟通无果,但数据不全其实是比较致命的,但是本次应用开发经验对其他应用功能开发依然有借鉴意义]

第二种方案: excel数据导入

1.涉及工具:
	Facebook数据分析主页 
	PHPExcel 

2. 逻辑流程(操作步骤):
		1)导出指定时间内的video_excel =>
		2)用户在前端上传excel文件 =>
		3)后端接收后,使用PHPExcel读取excel文件(/tmp/临时文件名) => 
		4)将相关文件内容存入数据库
		
3.遇到的问题&解决方案:
1) 问题一: PHPExcel的基本使用
	答: 因为涉及到代码模块,篇幅可能比较大,为了不干扰读者,本文以开发逻辑描述为主,PHPExcel的简单使用会单独写一遍博客描述
2) 问题二: 文件在哪里导出? 导出文件有哪些格式要求?
	答:
		A) 在视频分析数据主页右上角有个导出按钮;
		B) 文件可以导出xls格式(excel文件),也可以导出csv格式
		C) 注意事项: 务必使用xls格式导出,因为经过二者对比视频数据,发现xls文件中数据比csv文件中要齐全的多,虽然csv读取操作会更简单(PHP中使用file_get_content可以直接读取csv文件,返回一个多维数组;而读取xls文件需要借助于第三方类库,本次使用PHPExcel) 
		D) 操作步骤使用说明如图所示:
			![在这里插入图片描述](https://img-blog.csdnimg.cn/20190616204812870.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2R1cmluZ25vbmU=,size_16,color_FFFFFF,t_70)

4.注意事项:
	1) excel导出时间,点击选择的时间点是当天凌晨00:00:00,即20190501表示20105-01 00:00:00;若想导出201905整月数据:20190501-20190601,而不是20190501-20190531
	2) 友情提示: PHPExcel 官方更新截止到2019年1月,因时间精力有限,本次依旧使用PHPExcel, 新版本官方类库github链接: https://github.com/PHPOffice/PhpSpreadsheet 
	3) fb导出的excel文件内容可能为xml/html/xls格式,可统一另存为xlsx格式,再使用PHPExcel处理(务必打开再另存为xlsx,直接修改文件后缀名无效; 方法亲测有效)

5.小结:
	1)优点: 数据比第一种方案完善,可获取所有视频数据;
	2)缺点:需要客户端配合导入excel数据);PHP读取excel文件内容: PHPExcel

第三种方案: 爬虫扒取网页

1.涉及工具: 
	Facebook主页(以及fb账号,密码)
	Puppeteer 
		(puppeteer是google公司基于Node.js开发的爬虫工具,可以模拟用户的图形界面操作,中文文档: https://zhaoqize.github.io/puppeteer-api-zh_CN/#?product=Puppeteer&version=v1.17.0&show=api-event-response)
	
2. 逻辑流程(操作步骤):
	1)Puppeteer模拟用户登录 =>
	2)手动复制fb的cookie信息,并写入文件 => 
	3)模拟登录前先将cookie写入fb网站 => 
	4)根据fb网页流程到达指定页面 => 
	5)通过puppeteer读取dom信息,并写入文件/数据库
	
3.遇到的问题&解决方案:
	1)  问题一: fb对操作频繁的账号/IP是否有安全策略限制?
		答:是的,fb的确做了这方面的限制,操作频繁的账号容易被封账号/被封IP; 切记先把cookie信息存入文件中,登录前使用本地文件存储的cookie; 建议在国内某些网站上先完成写入cookie的操作,然后再开发,万一账号被封,国内申诉相对要简单一些
**友情提示: 可提前添加3个以上好友,封号时用以申诉,新账号频繁特别容易被封; 

	2)问题一:cookie有效期,以及cookie相关的安全策略
		答:
			A) fb的cookie有效期,好像是25个小时(可自行求证)
			B) fb网站的cookie信息无法使用document.cookie等js方法获取,可采用手动复制调试窗口的cookie信息,并存入本地文件中,毕竟cookie有效期在一天左右,一天只需要做一次cookie存储
	3) 问题三: fb网页还有哪些安全策略限制,
		 答:
		 	A)策略限制: fb网站出现弹窗提示,同时让页面被阴影页面覆盖,无法继续操作
			B)解决方案:
				a)方案一:本来想使用puppeteer图形界面操作,通过获取指定的网页像素坐标,执行puppeteer的鼠标点击事件,但是遗憾没有解决
				b)方案二: 通过设置浏览器的设置,禁止网站弹窗弹出,但是puppeteer是基于Node.js运行的,每次执行代码,Node.js会自动创建进程,打开一个浏览器,浏览器配置无法生效
				c)方案三: puppeteer操作dom元素,直接使得阴影页面失效style:display=none [有效]

4.注意事项:
	1) cookie有效期,好像是25个小时
	2) 切记要设置cookie写入,否则容易被封账号,被封IP,可提前添加3个以上好友,封号时用以申诉,新账号频繁特别容易被封
	3) fb的网页技术限制,如cookie不能读取,网站弹窗提示无法关闭导致操作流程中断
	
5.小结:
	1)优点: 可获取fb网站的所有参数;
	2)缺点: 需解决fb的网页策略限制,而且受fb网站操作流程影响,即需要实时跟进fb网站流程)


注意事项(**坑)

总结

三种方案对比(技术/产品角度, 学习成本,开发周期,人力,个人收获)
上面说了这么多,可能有点晕了,现在再总结对比一下三种方案:主要从技术/产品角度
1. 第一种方案
	1)技术角度:接口数据权威,操作可控性强,需熟悉时间研究Graph-SDK,但对于后续应用开发上手会很快
	2)产品角度:用户操作少,体验好,但是致命伤害是统计结果不完整(facebook的隐私保护和版权限制,经过粗略统计,大概有1/3的视频数据因视频内容涉及版权问题)
2. 第二种方案:
	1)技术角度:操作比较简单,不需要花时间熟悉Graph-SDK,也不需要花时间学习Puppeteer,主需要会简单操作PHPExcel等第三方类库,进行简单的xls文件读取
	2)产品角度:用户体验适中(相对于第一种和第三种方案),开发周期最短,能很快上线功能
3. 第三种方案:
	1)技术角度: 后端而言(本人PHPer),puppeteer是基于Node.js,需要时间学习接触新的东西,但是puppeteer操作流程比较简单(与用户界面操作一致),但可能因网站安全策略限制导致执行中断;随facebook网站用户操作流程变化而变化,需定期进行调整
	2)产品角度: 用户体验不好(需通过puppeteer用户的明文账号密码模拟用户登录行为),数据完整,统计结果准确,

4. 建议: *** 所以最终我采用的是第二种方案(excel数据导出导入),综合技术层面和产品层面,以及开发效率而言,第二种方案是最优的 

结语

1. 因为三种方案分别涉及不同的技术工具,牵扯的代码片段和细节较多,为了不影响读者了解本次逻辑流程,我会另外写三篇博客来介绍各自的技术工具,以及相关细节和demo
2.希望我这段时间的经历可以对大家有所帮助,欢迎提出不同见解,有遗漏之处还望指出,谢谢

你可能感兴趣的:(实践类)