移动设备识别及贴吧应用

本文主要介绍后端对移动设备的识别方法和方案,并详细介绍了贴吧的使用经验。

来自crispgm的原创

背景

随着移动时代的到来,移动上网用户的比例已经超过PC用户,其中移动浏览器的用户基数也得到了很大的提升,移动浏览器的访问也是用户的重要来源之一。这些用户通过移动端浏览器访问网页时,受限于网络状况、屏幕分辨率、操作交互方式和渲染能力等原因的影响,并不一定适用于平时专为PC浏览器设计的网页。

为此,许多网站会为移动web端做特别的优化。优化的方式有多种,其中,比较常见的几种方式是:

  1. 在进入页面时初步识别,并提供切换功能,用户手动选择
  2. 采用响应式页面设计,单个页面适应全部终端设备
  3. 对用户访问进行设备识别,决定进入的网页类型

其中,响应式页面设计方式并不依赖于主要基于屏幕分辨率和前端技术实现,并不依赖移动设备识别。而其它方式,则往往需要进行移动识别。

识别方式

User-Agent识别

对于设备识别,主要方式是通过User-Agent识别,原理上比较简单,就是对User-Agent进行文本匹配或正则表达式匹配。这种方法的主要难度在于User-Agent词典文件的收集。

对于基于User-Agent的设备识别,完全可以在运行层进行,这里推荐一个GitHub上比较火的PHP设备识别库——Mobile Detect,GitHub地址是https://github.com/serbanghita/Mobile-DetectMobile Detect是众多PHP框架或系统所使用的识别库(如:Wordpress/Lavarel等)。

Mobile Detect的使用方法很简单,只需包含文件,创建一个Mobile_Detect对象,就可以调用其丰富的库函数进行识别。

1
2
3
4
5
6
7
8
9
10
11
12
13
require_once 'Mobile_Detect.php';
$detect = new Mobile_Detect();

if ($detect->isMobile()) {
// 我是移动端
}
if ($detect->isTablet()) {
// 我是平板
}
if ($detect->isiOS()) {
// 我是iOS端
}
$detect->version('iPad'); // 获取iPad版本号

更多Demo,请访问https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples

IP识别

不过,针对国内的网络情况,有一个特殊的方式可以简化部分识别逻辑——IP识别。IP识别会针对国内几家移动电信运营商的入口IP进行识别,如果符合特征则会认为是移动设备,不再识别User-Agent。

这种方式,比起识别User-Agent更为高效简便,不用匹配庞大数量的字符串甚至是正则表达式。但也会有一个问题,就是通过手机热点访问的设备会被识别成手机。

贴吧应用

由于贴吧现在的架构对不同的服务分集群响应,因此目前需要在orp router层用nginx进行设备识别和分流,具体使用的是百度nginx技术小组开发的ngx_http_dna_module设备识别nginx扩展,设备识别使用的是wise/adaption识别库。对于不同设备的用户,会导入至不同版本的贴吧页面。

wise/adaption

对于C/C++模块需要进行设备识别,也可以调用此模块进行设备类型识别。用法非常简单,只需要初始化并传入http headers以及ip地址,就可以进行User-Agent + IP的复合式设备识别。

1
2
3
4
5
6
7
8
9
10
11
#include "adaption.h"
#include "adapt_dictentry.h"
#include "adaptor_def.h"

// 声明和初始化
static Adaption_intf g_adaptor;
g_adaptor.init(g_adaption_path);
// 识别函数
is_mobile = g_adaptor.is_mobile_device(&headers, (char *)ip);
is_pad = g_adaptor.is_pad_device(&headers);
device_type = g_adaptor.get_device_type(&headers, (char *)ip);

SVN地址:/app/wise/ta/adaption
PS:光有代码程序是跑不起来的,记得找他们现在的负责人要一份最新的词典文件!

ngx_http_dna_module

ngx_http_dna_module为nginx http handler扩展,运行于NGX_HTTP_POST_READ_PHASE阶段。

Directives

  • dna
    • Type: flag
    • Context: main, server, location
    • Default: off
    • Description: 模块开关
  • dna_adapt_path
    • Type: string
    • Context: main, server, location
    • Default: “./“
    • Description: wise/adaption 词典配置文件路径
  • dna_url_adaption
    • Type: string
    • Context: main, server, location
    • Default: “arg_device”
    • Description: 通过url参数指定设备类型的参数名
  • dna_cookie_adaption
    • Type: string
    • Context: main, server, location
    • Default: “cookie_device”
    • Description: 通过cookie指定设备类型的键名

Variables

  • $dna_device
    • Type: string
    • Values: [pc | mobile | pad]
    • Description: 变量为当前访问设备标识

router配置解析

1
2
3
4
5
# 开关和配置信息
dna on;
dna_adapt_path "/home/work/nginx/conf/adaption";
dna_url_adaption "tmp_device";
dna_cookie_adaption "tb_device";
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 进行识别和跳转
# 例子:智能版frs
# 注:nginx不支持嵌套,所以判断方式比较诡异
if ($dna_device = "mobile")
{
set $mobile 1;
}
if ($request_uri ~ "^/mo/q.*/m\?.*kw=|^/f\?.*kw=|^/mo/q.*/m?.*tn4=bdKSW.*sub4=|^/mo/q/topic_page/")
{
set $mobile "${mobile}frs";
}
if$mobile ~ "1frs")
{
rewrite ^(.*) /mo_wowap_frs$1 break;
break;
}
1
2
3
4
5
6
# 最终引入mo_wowap_frs集群
# ps:中间省略流量控制等部分内容,只用于示意
location /mo_wowap_frs {
proxy_pass http://tieba_mo_wowap_frs_server_name;
break;
}

引用

  1. 百度贴吧数据平台
  2. 百度nginx使用手册 - 设备识别扩展说明(dna) http://nginx.baidu.com/book/nginx_user_manual/module/dna.html