Go学堂

V1

2022/11/16阅读:142主题:橙心

「Go工具箱」解析http请求中的user-agent,就用这个包

大家好,我是渔夫子。「Go学堂」新推出“Go工具箱”系列,意在给大家分享使用go语言编写的、实用的、好玩的工具。

今天给大家推荐一个解析HTTP请求头中user-agent字段的库:user_agent 。目前腾讯蓝鲸智云配置平台都在用这个包。

user_agent小档案
star 734 used by 622
contributors 27 作者 mssola
功能简介 将HTTP请求中的User-Agent字段值解析成结构化的结构体。
项目地址 https://github.com/mssola/user_agent
相关知识 user-agent

一、User-Agent是什么

User-Agent叫做用户代理,是HTTP协议中请求头中的一个字段值。通过该字段值可以告诉网站服务器用户使用的什么产品发送的http请求。该信息一般发送请求的产品名称、操作系统、版本号等信息。大家熟知的浏览器其实就是所谓的一种用户代理。

通过谷歌的chrome浏览器,我们可以看到user-agent字段值如下: user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36

image.png
image.png

user-agent是一个文本字符串,其符合以下语法:

User-Agent: <product> / <product-version> <comment>

该语法我们可以称之为一个组成单元,在一个user-agent中可以有多个这样的组成单元,组成单元之间用空格分隔。

image.png
image.png

一般浏览器的user-agent的格式如下:

User-Agent: Mozilla/5.0 (<system-information>) <platform> (<platform-details>) <extensions>

看起来有点跟最上面user-agent的通用语法不一样。下面是chrome浏览器中一个http请求的真实的user-agent值。我们以该值为例来分解器结构:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36

该值中我们通过4种颜色划分了4个部分,每个部分实际上是通过空格划分的。每个部分实际上都是符合 / 的语法的。如下:

image.png
image.png

在这个浏览器的实例中,每个部分又代表了不同的信息。如下:

image.png
image.png

关于浏览器中UA还有一些有趣的发展历史,大家可以参考文末的参考链接。

二、User-Agent能做什么

2.1 根据用户使用浏览器的不同,显示不同的排版从而为用户提供更好的体验。这就是我们平时看到的,用手机访问谷歌和电脑访问是不一样的,这些是谷歌根据访问者的UA来判断的。

2.2 用于数据统计分析。例如可以根据user-agent中的信息统计来源于各平台(PC、mobile、平板等)、用户使用的操作系统(Android、iOS、Unix、Windows)等的数据。通过数据分析后进一步改善用户的体验。

当然,用户代理不仅仅是浏览器,还可以是机器人、网络爬虫。网站服务器可以根据user-agent进行识别,以输出不同的内容。

三、安装user-agent包

使用go get进行安装:

 go get github.com/mssola/user_agent

四、user-agent包的基本使用

我们看下user-agent包的使用。使用很简单,直接上代码:

package main

import (
    "fmt"

    "github.com/mssola/user_agent"
)

func main() {
    // The "New" function will create a new UserAgent object and it will parse
    // the given string. If you need to parse more strings, you can re-use
    // this object and call: ua.Parse("another string")
    ua := user_agent.New("Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1")

    fmt.Printf("%v\n", ua.Mobile())   // => true
    fmt.Printf("%v\n", ua.Bot())      // => false
    fmt.Printf("%v\n", ua.Mozilla())  // => "5.0"
    fmt.Printf("%v\n", ua.Model())    // => "Nexus One"

    fmt.Printf("%v\n", ua.Platform()) // => "Linux"
    fmt.Printf("%v\n", ua.OS())       // => "Android 2.3.7"

    name, version := ua.Engine()
    fmt.Printf("%v\n", name)          // => "AppleWebKit"
    fmt.Printf("%v\n", version)       // => "533.1"

    name, version = ua.Browser()
    fmt.Printf("%v\n", name)          // => "Android"
    fmt.Printf("%v\n", version)       // => "4.0"

    
    // Let's see an example with a bot.
    ua.Parse("Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")

    fmt.Printf("%v\n", ua.Bot())      // => true

    name, version = ua.Browser()
    fmt.Printf("%v\n", name)          // => Googlebot
    fmt.Printf("%v\n", version)       // => 2.1
}

该包的实现原理本质上就是对字符串按上面的规格进行解析。但同时需要考虑各种user-agent中的细微差别。所以该包不仅仅是一个简单的封装,而是需要具有对user-agent在各平台、各种场景下的深入了解才能做到的。

参考链接: 浏览器UA的发展历史:https://www.zhihu.com/question/306775584

浏览器UA的发展历史(英文版):https://webaim.org/blog/user-agent-string-history/

---特别推荐---

特别推荐:一个专注go项目实战、项目中踩坑经验及避坑指南、各种好玩的go工具的公众号。「Go学堂」,专注实用性,非常值得大家关注。点击下方公众号卡片,直接关注。关注送《100个go常见的错误》pdf文档。

分类:

后端

标签:

后端

作者介绍

Go学堂
V1