Go每日一库之170:user-agent

发布时间 2023-09-29 21:54:14作者: 阿瑞娜

一、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

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

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

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

一般浏览器的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个部分,每个部分实际上是通过空格划分的。每个部分实际上都是符合/ 的语法的。如下:

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

关于浏览器中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/