java⾃⼰实现解析处理user-agent获取设备信息ip-ua转化归因
前景提要
最近在做app投放的转化归因,⼏个搜索平台并不⼀定能获取到muid,于是需要⽤到ip-ua归因模式
⽹上粗略搜了⼀下,发现许多⽂章ua处理⽤的uaparser⼜或者user-agent-utils,随遂来源码看了看,对⼿机设备的划分太粗糙了,不符合要求。
准备⾃⼰写⼀个。
公司内已经上线使⽤,⽬前没发现问题
User-agent格式
写之前⾸先要了解ua的格式
鉴于不同平台的格式也会有不同,所以对主流平台进⾏统计并观察规律也是必要的。
User-Agent通常格式:
⾃定义标识 (平台) 引擎版本 浏览器版本号
eg:Mozilla/5.0 (iPhone; CPU iPhone OS 14_8_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1
实际上需要⽤到的就是第⼀个括号内的平台信息,内部信息⽤英⽂半⾓分号分开
常见格式:
ios 12.1(iPhone; CPU iPhone OS {os version})
(Linux; {os version}; {lang};{device name} Build/{core version})
截取ua中第⼀个括号的内容,依次分析内容。
这⾥和前端统计了常见流量来源的user-agent:
常见渠道user-agent
来源预估
占⽐
eg
safari20%Mozilla/5.0 (iPhone; CPU iPhone OS 14_8_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2
Mobile/15E148 Safari/604.1
百度17%
Mozilla/5.0 (Linux; Android 9; V1901A Build/P00610; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0
Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.27 SP-engine/2.37.0 baiduboxapp/12.28.5.10 (Baidu; P1 9) NABar/1.0
QQ 13%
Mozilla/5.0 (Linux; U; Android 9; zh-cn; LON-AL00 Build/HUAWEILON-AL00) AppleWebKit/537.36 (KHTML, like Gecko)
Version/4.0 Chrome/89.0.4389.72 MQQBrowser/12.1 Mobile Safari/537.36 COVC/045825
Mozilla/5.0 (Linux; Android 10; HarmonyOS; ELS-AN00; HMSCore 6.2.0.302) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/92.0.4515.105 HuaweiBrowser/12.0.1.300 Mobile Safari/537.36 -----------------f分割-------------Mozilla/5.0 (Linux;
Android 10; SEA-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.311 Mobile
Safari/537.36
华为
13%
⼩⽶10%
Mozilla/5.0 (Linux; U; Android 11; zh-cn; Redmi K30 Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.116 Mobile Safari/537.36 XiaoMi/MiuiBrowser/15.6.8-------------------------Mozilla/5.0 (iPhone;
U; CPU iPhone OS 5_1_1 like Mac OS X; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206
Safari/7534.48.3
XiaoMi/MiuiBrowser/15.6.8
uc10%Mozilla/5.0 (iPhone; CPU iPhone OS 15_1 like Mac OS X; zh-CN) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19B74 UCBrowser/13.6.4.1594 Mobile AliApp(TUnionSDK/0.1.20.4)------
------------------------------------Mozilla/5.0 (Linux; U; Android 11; zh-CN; Mi 10 Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108
UCBrowser/13.6.7.1148 Mobile
Safari/537.36
其他其他随缘
来源预估占⽐eg 可以看到,不同渠道还是有区别的。
代码也就完成了:
代码
/**
* User-Agent 处理类
* ⽤于⼴告回传时处理ua 从⽽获取设备信息
*
* User-Agent 通常格式:
* ⾃定义标识 (平台) 引擎版本 浏览器版本号
*
* eg:Mozilla/5.0 (iPhone; CPU iPhone OS 14_8_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1 *
* 实际上⽤到的就是第⼀个括号内的平台信息,内部信息⽤英⽂半⾓分号分开
*
*/
@Slf4j
public class UserAgentUtils {
/**
* 识别操作系统的正则,只配了ios ,鸿蒙,android
* 配置正则存在顺序(短路)
*/
private List <StrategyRule > systemInfoStrategy ;
/**
* 识别设备型号的正则
* 配置正则存在顺序(短路)
*/
private List <StrategyRule > deviceInfoStrategy ;
private static String OS_TYPE = "osType";
private static String OS_VERSION = "osVersion";
private static String OS_DEVICE = "mobileModel";
private static String IOS_OS = "ios";
public UserAgentUtils (List <StrategyRule > systemInfoStrategy , List <StrategyRule > deviceInfoStrategy ){
this .systemInfoStrategy = systemInfoStrategy ;
this .deviceInfoStrategy = deviceInfoStrategy ;
}
public boolean compareByUserAgent (String ua1, String ua2, String ip1, String ip2){
return analysisUserAgent (ua1, ip1).equalWith (analysisUserAgent (ua2, ip2));
}
/**
* 先获取操作系统的类别(android x , ,HarmonyOS )
* 再去截取⼿机型号
* @param ua
* @param ip
* @return
*/
public UserAgentDevice analysisUserAgent (String ua , String ip ){
UserAgentDevice agentDevice = new UserAgentDevice ();
agentDevice .setIp (ip );
Map <String , String > systemInfo = handleByStrategy (ua , systemInfoStrategy );
if (systemInfo == null ){
log .warn ("不可识别的系统,可能是pc 端之类没有做正则的类别,ua:{}",ua );
} else {
agentDevice .setMobileSystem (systemInfo .get (OS_TYPE ));
agentDevice .setSystemVersion (systemInfo .get (OS_VERSION ));
}
if(IOS_OS.MobileSystem())){
//ios 型号⽤ios+版本号拼接
agentDevice.MobileSystem()+ SystemVersion().split(".")[0]);
return agentDevice;
}
Map<String, String> osInfo =handleByStrategy(ua, deviceInfoStrategy);
if(osInfo ==null){
log.warn("未获取到⼿机型号,可能是未配置的渠道样式,ua:{}",ua);
}else{
agentDevice.(OS_DEVICE));
}
return agentDevice;
}
/**
* 针对不同功能,ua处理⽅法不同
* 这是⼀个统⼀处理⽅法
* @param ua
* @param strategyList
* @return
*/
public static Map<String, String>handleByStrategy(String ua,List<StrategyRule> strategyList){
Map<String, String> result =new HashMap<>();
for(StrategyRule rule : strategyList){
for(String regular : RegularList()){
/
/匹配正则
Matcher matcher = Patternpile(regular,Pattern.CASE_INSENSITIVE).matcher(ua);
if(matcher.find()){
int k =1;
//对捕获组做处理以适应不同返回
for(StrategyFun f : FunList()){
result.putAll(f.up(k++)));
}
return result;
}
}
}
return null;
}
@Data
public static class StrategyRule{
/**
* 正则list
*/
private List<String> regularList;
private List<StrategyFun> funList;
}
@Data
public static class StrategyFun{
/**
* 对应直接返回键值对情况
*/
String name;
String value;
boolean valueFlag =false;
/**
* 对应replace的情况
*/
String r1;
String r2;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论