Go每日一库之170: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

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包的使用。使用很简单,直接上代码:

代码语言:javascript
复制
package main

import (
"fmt"

&#34;github.com/mssola/user_agent&#34;

)

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(&#34;%v\n&#34;, ua.Mobile())   // =&gt; true
fmt.Printf(&#34;%v\n&#34;, ua.Bot())      // =&gt; false
fmt.Printf(&#34;%v\n&#34;, ua.Mozilla())  // =&gt; &#34;5.0&#34;
fmt.Printf(&#34;%v\n&#34;, ua.Model())    // =&gt; &#34;Nexus One&#34;

fmt.Printf(&#34;%v\n&#34;, ua.Platform()) // =&gt; &#34;Linux&#34;
fmt.Printf(&#34;%v\n&#34;, ua.OS())       // =&gt; &#34;Android 2.3.7&#34;

name, version := ua.Engine()
fmt.Printf(&#34;%v\n&#34;, name)          // =&gt; &#34;AppleWebKit&#34;
fmt.Printf(&#34;%v\n&#34;, version)       // =&gt; &#34;533.1&#34;

name, version = ua.Browser()
fmt.Printf(&#34;%v\n&#34;, name)          // =&gt; &#34;Android&#34;
fmt.Printf(&#34;%v\n&#34;, version)       // =&gt; &#34;4.0&#34;


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

fmt.Printf(&#34;%v\n&#34;, ua.Bot())      // =&gt; true

name, version = ua.Browser()
fmt.Printf(&#34;%v\n&#34;, name)          // =&gt; Googlebot
fmt.Printf(&#34;%v\n&#34;, version)       // =&gt; 2.1

}

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

参考链接:

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

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