Django建站场景下如何通过短链接采集网站访客数据
Django短链接访客数据采集方案
核心结论先行
采集User Agent(UA)字符串不是满足你全量需求的最优方案,它只是客户端基础信息采集的其中一个环节,无法单独完成IP、设备ID等维度的数据获取。
所有短链接访问的采集前提是:你必须把短链的解析跳转逻辑托管在自己的Django服务上,不能配置直接跳转到目标地址,要在跳转的中间层完成数据埋点,再执行跳转。
各需求维度的具体采集方式
你需要的三类数据,没有单一方案能一次性拿全,要分维度处理:
- 操作系统(OS)信息
最通用的方式就是从请求头里取原始UA字符串,Django中可以直接通过request.META.get('HTTP_USER_AGENT')获取。不建议自己写正则解析UA内容,直接用user-agents这类成熟库,传入原始UA就能直接返回结构化的OS类型/版本、设备类型(手机/PC/平板)、浏览器类型/版本数据,普通场景下准确率能到85%以上。
注意UA存在可篡改的问题:爬虫、代理工具、隐私浏览器都会修改UA内容,所以OS识别结果不要作为强校验依据。 - IP地址
不要直接用request.META.get('REMOTE_ADDR')取值,如果你的服务前面挂了CDN、Nginx反向代理或者负载均衡,这个值拿到的是代理节点的IP,不是访客真实IP。要优先从X-Forwarded-For请求头中取第一个非可信代理段的IP,Django中提前配置好SECURE_PROXY_SSL_HEADER参数和可信代理IP段后,用request.META.get('HTTP_X_FORWARDED_FOR', '').split(',')[0].strip()就能拿到真实访客IP,记得加IP格式校验,防止恶意伪造请求头。
如果需要IP对应的归属地、运营商信息,用离线IP库本地解析即可,不要依赖外部接口,避免引入性能问题和数据泄露风险。 - 设备ID
默认的HTTP请求头里不会携带任何设备唯一标识,不管是UA还是其他默认头都拿不到这个数据,浏览器出于隐私安全限制,也不会给普通网页开放系统级硬件ID(比如IMEI、IDFA)的读取权限,可行的落地方案只有两类:- 第一方Cookie标识:访客第一次访问短链时,在跳转响应中写入一个有效期1-2年的HttpOnly Cookie,值为随机生成的UUID,作为该访客的临时标识,后续同个浏览器再访问时直接读取Cookie里的ID即可。缺点是用户清理Cookie、开启无痕模式时,ID会重置。
- 浏览器指纹:如果需要更高的跨会话识别率,可以加一个加载耗时极短的中间跳转页,嵌入轻量JS采集屏幕分辨率、时区、系统字体列表、Canvas/WebGL渲染特征等信息,组合生成指纹ID作为设备标识,识别率比纯Cookie高,但高版本浏览器的隐私限制会导致指纹一致性下降,也做不到100%准确。
UA方案的优劣势边界
UA采集的优势是实现零成本,不需要前端配合,服务端直接就能取到值,是识别访客基础环境的最低成本方案;但缺陷也很明确:
- 完全无法获取你需要的IP、设备ID两类核心数据
- 内容可被随意篡改,伪造成本极低
- 目前主流浏览器已经在逐步缩减UA字段携带的信息量,后续靠UA能获取的环境数据会越来越少
所以它只能作为整套采集方案的基础组成部分,不能作为唯一方案。
Django侧落地参考代码
先安装依赖:pip install user-agents
短链跳转视图的核心逻辑示例:
import uuid from django.http import HttpResponseRedirect from user_agents import parse from your_app.models import ShortLinkVisitRecord def short_jump_view(request, short_code): # 获取真实访客IP xff = request.META.get('HTTP_X_FORWARDED_FOR') real_ip = xff.split(',')[0].strip() if xff else request.META.get('REMOTE_ADDR', '') # 解析UA获取OS、设备类型信息 raw_ua = request.META.get('HTTP_USER_AGENT', '') ua_parsed = parse(raw_ua) os_info = f"{ua_parsed.os.family} {ua_parsed.os.version_string}" device_type = ua_parsed.device.family # 读取/写入访客标识Cookie visitor_id = request.COOKIES.get('site_visitor_id') # 提前查好短链对应的目标跳转地址 target_url = get_target_url_by_shortcode(short_code) resp = HttpResponseRedirect(target_url) if not visitor_id: visitor_id = str(uuid.uuid4()) resp.set_cookie( key='site_visitor_id', value=visitor_id, max_age=365*24*3600, # 有效期1年 httponly=True, secure=request.is_secure(), samesite='Lax' ) # 写入访问记录 ShortLinkVisitRecord.objects.create( short_code=short_code, ip=real_ip, os=os_info, device_type=device_type, visitor_id=visitor_id, raw_ua=raw_ua ) return resp
如果要接入浏览器指纹采集,不要直接返回302跳转,先返回一个体积极小的中间页,JS执行完指纹采集上报后,再自动跳转到目标地址即可。
内容的提问来源于stack exchange,提问作者ek1669
相关产品推荐
相关产品推荐

