Python port of Browserscope's user agent parser for parsing user agent strings into browser, OS, and device information
npx @tessl/cli install tessl/pypi-ua-parser@0.18.0A Python port of Browserscope's user agent parser that extracts detailed information about browsers, operating systems, and devices from user agent strings. The library provides comprehensive parsing capabilities with built-in caching for high-performance scenarios and supports a wide range of user agents including desktop browsers, mobile devices, bots, and other web clients.
pip install ua-parserfrom ua_parser import user_agent_parser
from ua_parser import VERSIONDirect function imports:
from ua_parser.user_agent_parser import Parse, ParseUserAgent, ParseOS, ParseDevicefrom ua_parser import user_agent_parser
# Example user agent string
ua_string = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.104 Safari/537.36'
# Parse all components (browser, OS, device)
result = user_agent_parser.Parse(ua_string)
print(result)
# {
# 'user_agent': {'family': 'Chrome', 'major': '41', 'minor': '0', 'patch': '2272'},
# 'os': {'family': 'Mac OS X', 'major': '10', 'minor': '9', 'patch': '4', 'patch_minor': None},
# 'device': {'family': 'Mac', 'brand': 'Apple', 'model': 'Mac'},
# 'string': 'Mozilla/5.0...'
# }
# Parse only browser information
browser = user_agent_parser.ParseUserAgent(ua_string)
print(browser)
# {'family': 'Chrome', 'major': '41', 'minor': '0', 'patch': '2272'}
# Parse only OS information
os_info = user_agent_parser.ParseOS(ua_string)
print(os_info)
# {'family': 'Mac OS X', 'major': '10', 'minor': '9', 'patch': '4', 'patch_minor': None}
# Parse only device information
device = user_agent_parser.ParseDevice(ua_string)
print(device)
# {'family': 'Mac', 'brand': 'Apple', 'model': 'Mac'}Parses the complete user agent string to extract browser, operating system, and device information in a single operation.
def Parse(user_agent_string, **jsParseBits):
"""
Parse all components of a user agent string.
Args:
user_agent_string (str): The full user-agent string
**jsParseBits: Deprecated JavaScript override parameters (deprecated)
Returns:
dict: Dictionary with keys 'user_agent', 'os', 'device', 'string'
- user_agent: Browser information with 'family', 'major', 'minor', 'patch'
- os: OS information with 'family', 'major', 'minor', 'patch', 'patch_minor'
- device: Device information with 'family', 'brand', 'model'
- string: Original user agent string (added by caching mechanism)
"""Extracts browser and user agent information including family name, major version, minor version, and patch version.
def ParseUserAgent(user_agent_string, **jsParseBits):
"""
Parse user agent string for browser information only.
Args:
user_agent_string (str): The full user-agent string
**jsParseBits: Deprecated JavaScript override parameters (deprecated)
Returns:
dict: Browser information with keys:
- family (str): Browser family name (e.g., 'Chrome', 'Firefox'), defaults to 'Other'
- major (str|None): Major version number
- minor (str|None): Minor version number
- patch (str|None): Patch version number
"""Extracts operating system information including OS family, major version, minor version, patch version, and patch minor version.
def ParseOS(user_agent_string, **jsParseBits):
"""
Parse user agent string for operating system information only.
Args:
user_agent_string (str): The full user-agent string
**jsParseBits: Deprecated JavaScript override parameters (deprecated)
Returns:
dict: OS information with keys:
- family (str): OS family name (e.g., 'Mac OS X', 'Windows'), defaults to 'Other'
- major (str|None): Major version number
- minor (str|None): Minor version number
- patch (str|None): Patch version number
- patch_minor (str|None): Patch minor version number
"""Extracts device information including device family, brand, and model.
def ParseDevice(user_agent_string, **jsParseBits):
"""
Parse user agent string for device information only.
Args:
user_agent_string (str): The full user-agent string
**jsParseBits: Deprecated JavaScript override parameters (deprecated)
Returns:
dict: Device information with keys:
- family (str): Device family name (e.g., 'iPhone', 'Mac'), defaults to 'Other'
- brand (str|None): Device brand (e.g., 'Apple', 'Samsung')
- model (str|None): Device model (e.g., 'iPhone', 'Galaxy S4')
"""Formats parsed user agent and OS information into human-readable strings.
def PrettyUserAgent(family, v1=None, v2=None, v3=None):
"""
Format user agent information into a readable string.
Args:
family (str): Browser family name
v1 (str, optional): Major version
v2 (str, optional): Minor version
v3 (str, optional): Patch version
Returns:
str: Formatted string like 'Chrome 41.0.2272' or 'Firefox 3.5.5'
"""
def PrettyOS(os, os_v1=None, os_v2=None, os_v3=None, os_v4=None):
"""
Format OS information into a readable string.
Args:
os (str): OS family name
os_v1 (str, optional): Major version
os_v2 (str, optional): Minor version
os_v3 (str, optional): Patch version
os_v4 (str, optional): Patch minor version
Returns:
str: Formatted string like 'Mac OS X 10.9.4' or 'Windows 8.1'
"""Generates filter parameters for JavaScript overrides (legacy functionality).
def GetFilters(user_agent_string, js_user_agent_string=None, js_user_agent_family=None, js_user_agent_v1=None, js_user_agent_v2=None, js_user_agent_v3=None):
"""
Return optional arguments that should be saved and used to query.
Args:
user_agent_string (str): The full user-agent string
js_user_agent_string (str, optional): JavaScript user agent string override
js_user_agent_family (str, optional): JavaScript family override
js_user_agent_v1 (str, optional): JavaScript version 1 override
js_user_agent_v2 (str, optional): JavaScript version 2 override
js_user_agent_v3 (str, optional): JavaScript version 3 override
Returns:
dict: Dictionary of filter parameters for non-None/non-empty values
"""Internal utility function for performing regex group substitutions in replacement strings used by parser classes.
def MultiReplace(string, match):
"""
Perform regex group substitutions in a replacement string.
Args:
string (str): String containing $1, $2, etc. placeholders
match (re.Match): Regex match object with captured groups
Returns:
str|None: String with substitutions applied, or None if result is empty
"""These functions are deprecated but still available for backwards compatibility.
def ParseWithJSOverrides(user_agent_string, js_user_agent_string=None, js_user_agent_family=None, js_user_agent_v1=None, js_user_agent_v2=None, js_user_agent_v3=None):
"""
Parse user agent with JavaScript overrides (deprecated).
Args:
user_agent_string (str): The full user-agent string
js_user_agent_string (str, optional): JavaScript user agent string override
js_user_agent_family (str, optional): JavaScript family override
js_user_agent_v1 (str, optional): JavaScript version 1 override
js_user_agent_v2 (str, optional): JavaScript version 2 override
js_user_agent_v3 (str, optional): JavaScript version 3 override
Returns:
tuple: (family, v1, v2, v3) version information
Deprecated:
Use Parse or specialized parsers instead
"""
def Pretty(family, v1=None, v2=None, v3=None):
"""
Format user agent information into readable string (deprecated).
Args:
family (str): Browser family name
v1 (str, optional): Major version
v2 (str, optional): Minor version
v3 (str, optional): Patch version
Returns:
str: Formatted string like 'Chrome 41.0.2272' or 'Firefox 3.5.5'
Deprecated:
Use PrettyUserAgent instead
"""The library provides parser classes for advanced usage and custom regex patterns. These are primarily used internally but can be instantiated directly for custom parsing scenarios.
class UserAgentParser:
"""Parser for extracting user agent (browser) information."""
def __init__(self, pattern, family_replacement=None, v1_replacement=None, v2_replacement=None):
"""
Initialize UserAgentParser.
Args:
pattern (str): Regular expression pattern
family_replacement (str, optional): Override for family name
v1_replacement (str, optional): Override for version 1
v2_replacement (str, optional): Override for version 2
"""
def Parse(self, user_agent_string):
"""
Parse user agent string and return version information.
Args:
user_agent_string (str): User agent string to parse
Returns:
tuple: (family, v1, v2, v3) version information
"""
def MatchSpans(self, user_agent_string):
"""
Get match span positions for regex groups.
Args:
user_agent_string (str): User agent string to parse
Returns:
list: List of (start, end) tuples for each regex group
"""
class OSParser:
"""Parser for extracting operating system information."""
def __init__(self, pattern, os_replacement=None, os_v1_replacement=None, os_v2_replacement=None, os_v3_replacement=None, os_v4_replacement=None):
"""
Initialize OSParser.
Args:
pattern (str): Regular expression pattern
os_replacement (str, optional): Override for OS name
os_v1_replacement (str, optional): Override for OS version 1
os_v2_replacement (str, optional): Override for OS version 2
os_v3_replacement (str, optional): Override for OS version 3
os_v4_replacement (str, optional): Override for OS version 4
"""
def Parse(self, user_agent_string):
"""
Parse user agent string and return OS information.
Args:
user_agent_string (str): User agent string to parse
Returns:
tuple: (os, os_v1, os_v2, os_v3, os_v4) OS information
"""
def MatchSpans(self, user_agent_string):
"""
Get match span positions for regex groups.
Args:
user_agent_string (str): User agent string to parse
Returns:
list: List of (start, end) tuples for each regex group
"""
class DeviceParser:
"""Parser for extracting device information."""
def __init__(self, pattern, regex_flag=None, device_replacement=None, brand_replacement=None, model_replacement=None):
"""
Initialize DeviceParser.
Args:
pattern (str): Regular expression pattern
regex_flag (str, optional): Regex flags ('i' for case insensitive)
device_replacement (str, optional): Override for device family
brand_replacement (str, optional): Override for device brand
model_replacement (str, optional): Override for device model
"""
def Parse(self, user_agent_string):
"""
Parse user agent string and return device information.
Args:
user_agent_string (str): User agent string to parse
Returns:
tuple: (device, brand, model) device information
"""
def MatchSpans(self, user_agent_string):
"""
Get match span positions for regex groups.
Args:
user_agent_string (str): User agent string to parse
Returns:
list: List of (start, end) tuples for each regex group
"""VERSION: tuple
"""Version tuple from ua_parser package (from ua_parser.VERSION)."""
MAX_CACHE_SIZE = 200
"""Maximum size of internal parsing cache before it gets cleared."""
USER_AGENT_PARSERS: list
"""List of UserAgentParser instances used for parsing browser information."""
OS_PARSERS: list
"""List of OSParser instances used for parsing operating system information."""
DEVICE_PARSERS: list
"""List of DeviceParser instances used for parsing device information."""The parser functions validate input types and raise appropriate exceptions:
TypeError: Raised when user_agent_string is not a string typefrom ua_parser import user_agent_parser
user_agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
]
results = []
for ua in user_agents:
parsed = user_agent_parser.Parse(ua)
results.append({
'original': ua,
'browser': f"{parsed['user_agent']['family']} {parsed['user_agent']['major']}",
'os': parsed['os']['family'],
'device': parsed['device']['family']
})from ua_parser import user_agent_parser
def safe_parse(user_agent_string):
try:
if not isinstance(user_agent_string, str):
raise TypeError("User agent must be a string")
return user_agent_parser.Parse(user_agent_string)
except TypeError as e:
print(f"Invalid input: {e}")
return Nonefrom ua_parser.user_agent_parser import UserAgentParser
# Create custom parser for specific pattern
custom_parser = UserAgentParser(
pattern=r'MyBot/(\d+)\.(\d+)',
family_replacement='MyBot'
)
result = custom_parser.Parse('MyBot/2.1 crawler')
# Returns: ('MyBot', '2', '1', None)