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