瀏覽器訪問網站時,會提交UserAgent信息,裏面包含操做系統/瀏覽器類型/渲染引擎,能夠據此大體評估網站的客戶端分佈。特別是移動設備會在UserAgent中包含設備型號信息,因此有可能根據UserAgent分析移動設備類型,進而針對不一樣設備實施改善用戶體驗等優化工做。git
看一個UserAgent的例子:github
Mozilla/5.0 (Linux; Android 4.4.2; Che2-TL00M Build/HonorChe2-TL00M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36正則表達式
這是來從Android 4.4.2的華爲手機Che2-TL00M的HTTP請求中提取出來的UserAgent信息,使用瀏覽器是Chrome30. 不少網站會根據UserAgent信息判斷應該如何給客戶端應答。但因爲UserAgent內容沒有規範可循,各個瀏覽器廠家能夠自行定義其內容,甚至普通用戶能夠在訪問網站時,經過工具自行修改UserAgent信息,好比Chrome就能夠幹這件事。各瀏覽器廠商爲了服務器判斷時獲得赦免,會加入Mozilla/Safari/AppleWebKit/Geko等字樣,都是欺詐。所以,網站服務器收到的UserAgent不必定徹底準確,但能動手修改UA信息的人畢竟佔少數,若是網站流量比較大,從UA中提取的信息仍是能大體看到客戶端的分佈情況。ubuntu
如何獲得UserAgent?首先從AccessLog中提取UserAgent字段,通常CDN或者採用W3C(IIS)或者採用NCSA(Apache)都有標準的格式,網絡上也有不少提取UA的方法。瀏覽器
提取出來的UserAgent如何解析?能夠本身寫正則表達式解析你想要的信息,不過要想應付種類繁雜的操做系統/瀏覽器版本,仍是要下一番功夫的。好在,有人已經作了這件事,並公開了源碼:服務器
https://github.com/HaraldWalker/user-agent-utils網絡
這個小工具很方便,經過一行代碼:UserAgent.parseUserAgentString(ua),能夠提取數據結構
設備類型:Computer / Mobile / Tablet / Game Console / Wearable 等;工具
操做系統:Windows x / Linux / Android / Mac OS / iOS / Blackberry / Chrome OS / MeeGo / Symbian / BADA 等,幾乎都有了,包括操做系統版本;優化
瀏覽器:IE / Edge / Firefox / Safari / Chrome / OPERA / DOLFIN / THUNDERBIRD / SEAMONKEY 等,還有不少沒用過甚至沒據說過的;
試用了一下,速度仍是很快的。但有些問題:
問題1,設備類型對Tablet的判斷有些混亂,把Red Mi和索愛 LT26i / LT29i等都判斷成Tablet,查看代碼發現它是根據操做系統關鍵字判斷設備類型,其Android操做系統數據結構定義:
// commented by , many devices can not be distinguished as mobile or tablet just by [whether it's useragent contails "mobile"] ANDROID( OSManufacturer.GOOGLE,null, 0, "Android", new String[] { "Android" }, new String[] {"Ubuntu"}, DeviceType.MOBILE, null ), ANDROID5( OSManufacturer.GOOGLE,OperatingSystem.ANDROID, 5, "Android 5.x", new String[] { "Android 5", "Android-5" }, new String[] { "glass" }, DeviceType.MOBILE, null ), //ANDROID5_TABLET(OSManufacturer.GOOGLE,OperatingSystem.ANDROID5, 50, "Android 5.x Tablet", new String[] { "Android 5", "Android-5"}, new String[] { "mobile", "glass"}, DeviceType.TABLET, null ), ANDROID4( OSManufacturer.GOOGLE,OperatingSystem.ANDROID, 4, "Android 4.x", new String[] { "Android 4", "Android-4" }, new String[] { "glass", "ubuntu"}, DeviceType.MOBILE, null ), //ANDROID4_TABLET(OSManufacturer.GOOGLE,OperatingSystem.ANDROID4, 40, "Android 4.x Tablet", new String[] { "Android 4", "Android-4"}, new String[] { "mobile", "glass", "ubuntu"}, DeviceType.TABLET, null ), //ANDROID4_WEARABLE(OSManufacturer.GOOGLE,OperatingSystem.ANDROID, 400, "Android 4.x", new String[] { "Android 4" }, new String[] {"ubuntu"}, DeviceType.WEARABLE, null ), //ANDROID3_TABLET(OSManufacturer.GOOGLE,OperatingSystem.ANDROID, 30, "Android 3.x Tablet", new String[] { "Android 3" }, null, DeviceType.TABLET, null ), // as long as there are not Android 3.x phones this should be enough ANDROID2( OSManufacturer.GOOGLE,OperatingSystem.ANDROID, 2, "Android 2.x", new String[] { "Android 2" }, null, DeviceType.MOBILE, null ), //ANDROID2_TABLET(OSManufacturer.GOOGLE,OperatingSystem.ANDROID2, 20, "Android 2.x Tablet", new String[] { "Kindle Fire", "GT-P1000","SCH-I800" }, null, DeviceType.TABLET, null ), ANDROID1( OSManufacturer.GOOGLE,OperatingSystem.ANDROID, 1, "Android 1.x", new String[] { "Android 1" }, null, DeviceType.MOBILE, null ),
能夠看到Android->Android x ->Android x Tablet 是一個嵌套結構,而且alias定義new String[] { "Android 4", "Android-4" }在Mobile和Tablet是同樣的,正是用aliases關鍵字對UA信息進行設備類型判斷的, 在判斷的時候,會優先深度遍歷這個嵌套,若是UA中不包含mobile字樣,就斷定爲Tablet,若是包含mobile字樣,就斷定爲Mobile,這在上面提到的小米和索愛等機型上不適用,形成Tablet統計結果有很大誤差。因此我將Android Tablet的定義都屏蔽了,統計結果中Android機型統一看成Mobile設備。
問題2,設備類型不支持智能電視,不少廠家已經推出Android電視,確實有用戶用它訪問網站,但應該是小衆用戶,對整體分析結果影響不大,若是關注來自TV的流量,可自行添加判斷邏輯
問題3,瀏覽器不包含對國產品牌360,搜狗,世界之窗,UC等的支持,須要本身添加相應品牌的識別邏輯
問題4,不能提取移動設備品牌信息,我本身添加了國內常見品牌的提取邏輯,實驗了一下,提取結果片斷以下(從左至右:DeviceType, DeviceBrand, OS, Browser, PV)
從結果看,Android機型的Browser中頻繁出現Mobile Safari,因此這個小工具對Browser的提取不太理想。
折騰了近一天一晚上,終於能夠對UserAgent作分析報告了。