如何使用Flask获取用户代理?

130

我正在尝试使用Flask获取用户代理,但是我要么找不到它的文档,要么它没有告诉我。

5个回答

221
from flask import request
request.headers.get('User-Agent')
你还可以使用 request.user_agent 对象,其中包含以下基于用户代理字符串创建的属性:
  • platform (windows, linux, macos, 等等)
  • browser (chrome, firefox, msie, 等等)
  • version
  • language
  • string (== request.headers.get('User-Agent'))

注意:从 werkzeug 2.0 开始,已弃用对 request.user_agent 的解析数据;如果你想继续获得详细信息,需要使用自定义的 UserAgent 实现,并将其设置为自定义 Request 子类的 user_agent_class,该子类被设置为 Flask 实例(或一个子类)上的 request_class

以下是一个使用 ua-parser 的示例实现:

from ua_parser import user_agent_parser
from werkzeug.user_agent import UserAgent
from werkzeug.utils import cached_property


class ParsedUserAgent(UserAgent):
    @cached_property
    def _details(self):
        return user_agent_parser.Parse(self.string)

    @property
    def platform(self):
        return self._details['os']['family']

    @property
    def browser(self):
        return self._details['user_agent']['family']

    @property
    def version(self):
        return '.'.join(
            part
            for key in ('major', 'minor', 'patch')
            if (part := self._details['user_agent'][key]) is not None
        )

3
看起来 request.user_agent 已经被弃用,并将在 Flask 2.1 中被移除。 链接:https://werkzeug.palletsprojects.com/en/2.0.x/utils/?highlight=user%20agent#module-werkzeug.user_agent - user2682863
1
部分正确:属性及其.string将保留;但是解析的细节将消失,因为如果需要此功能,应该使用类似ua-parser的工具。 - ThiefMaster

36

如果您使用

request.headers.get('User-Agent')

您可能会得到:

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36

如果您使用

request.user_agent

你可能会得到类似这样的结果:

  • user_agent.platform:windows
  • user_agent.browser:chrome
  • user_agent.version:45.0.2454.101
  • user_agent.language:无
  • user_agent.string:Mozilla/5.0(Windows NT 6.1;WOW64)AppleWebKit/537.36(KHTML,像Gecko一样)Chrome/45.0.2454.101 Safari/537.36

为什么语言是None?有没有简单的方法获取语言? - Faminator
@Faminator 如果客户端浏览器没有设置语言字段,那么服务器就无法获取它,因此它只会显示为 None。 - ffledgling

29
flask.request.user_agent.string

请在您的帖子中提供更详细的信息。 - Heewoon

2

UA通常不包含语言信息。如果您想获取浏览器中设置的语言信息,可以使用以下方法:

request.accept_languages

它将为您提供语言列表。例如:
LanguageAccept([('en-US', 1), ('en', 0.5)])

要访问第一个值,可以使用

request.accept_languages[0][0]

这将导致字符串输出。
'en-US'

有关“accept_language”标头的详细信息:https://www.w3.org/International/questions/qa-lang-priorities


2
这个问题需要更多的信息。这个库似乎符合收集来自Flask的大量信息的要求,并且有获取应用程序上下文中此信息的示例调用。

https://pythonhosted.org/Flask-Track-Usage/

使用方法以这种格式存储:
[
    {
            'url': str,
            'user_agent': {
                'browser': str,
                'language': str,
                'platform': str,
                'version': str,
            },
            'blueprint': str,
            'view_args': dict or None
            'status': int,
            'remote_addr': str,
            'xforwardedfor': str,
            'authorization': bool
            'ip_info': str or None,
            'path': str,
            'speed': float,
            'date': datetime,
    },
    {
        ....
    }
]

这是图书馆收集数据的其中一个位置: 在https://github.com/ashcrow/flask-track-usage/blob/master/src/flask_track_usage/init.py大约158行左右。
    data = {
        'url': ctx.request.url,
        'user_agent': ctx.request.user_agent,
        'server_name': ctx.app.name,
        'blueprint': ctx.request.blueprint,
        'view_args': ctx.request.view_args,
        'status': response.status_code,
        'remote_addr': ctx.request.remote_addr,
        'xforwardedfor': ctx.request.headers.get(
            'X-Forwarded-For', None),
        'authorization': bool(ctx.request.authorization),
        'ip_info': None,
        'path': ctx.request.path,
        'speed': float(speed),
        'date': int(time.mktime(current_time.timetuple())),
        'content_length': response.content_length,
        'request': "{} {} {}".format(
            ctx.request.method,
            ctx.request.url,
            ctx.request.environ.get('SERVER_PROTOCOL')
        ),
        'url_args': dict(
            [(k, ctx.request.args[k]) for k in ctx.request.args]
        ),
        'username': None,
        'track_var': g.track_var
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接