Mobile Device Detection
By John Boxall
How do you detect a mobile browser?
One solution relies on inspecting the User-Agent header that a browser sends when it makes an HTTP request. In theory each browser sends an identifiable User-Agent. If we knew what browsers sent which User-Agents then we could identify the mobile browsers!
The problem is there are about a bajillion unique mobile device User-Agents and no clear way to distinguish what makes a User-Agent mobile. But what if we reversed the problem?
How do you detect a desktop browser?
At some point someone smart sat down and decided that desktop User-Agents would be predictable. Turns out most of them include the name of the desktop OS they are running inside the string. If we know what browsers include a desktop OS string then ..!
Enough talk, let's code it.
First we'll setup regular expressions to detect desktop OSs in User-Agents:
import re RE_DESKTOP = re.compile(r"(windows|linux|os\s+[x9]|solaris|bsd)", re.I)
Next we'll pick the browser User-Agent from an HTTP request and use our regular expressions to test whether it looks like the browser is running on a desktop OS:
def is_desktop(user_agent):
return bool(RE_DESKTOP.search(user_agent))
def view(request):
user_agent = request.headers.get('HTTP_USER_AGENT', '')
if is_desktop(user_agent):
return desktop_response()
else:
return mobile_response()
Like most theories there are a few "except after c" clauses. Specifically:
- Mobile browsers whose User-Agents look like desktop browsers (mr. iphone)
- Bots whose User-Agents don't contain a desktop OS (looking at your googlebot)
- Mobile browsers that send User-Agents in a HTTP-X header (operrrrra!)
import re
# Some mobile browsers which look like desktop browsers.
RE_MOBILE = re.compile(r"(iphone|ipod|blackberry|android|palm|windows\s+ce)", re.I)
RE_DESKTOP = re.compile(r"(windows|linux|os\s+[x9]|solaris|bsd)", re.I)
RE_BOT = re.compile(r"(spider|crawl|slurp|bot)", re.I)
def is_desktop(user_agent):
"""
Anything that looks like a phone isn't a desktop.
Anything that looks like a desktop probably is.
Anything that looks like a bot should default to desktop.
"""
return not bool(RE_MOBILE.search(user_agent)) and \
bool(RE_DESKTOP.search(user_agent)) or \
bool(RE_BOT.search(user_agent))
def get_user_agent(request):
# Some mobile browsers put the User-Agent in a HTTP-X header
return request.headers.get('HTTP_X_OPERAMINI_PHONE_UA') or \
request.headers.get('HTTP_X_SKYFIRE_PHONE') or \
request.headers.get('HTTP_USER_AGENT', '')
def view(request):
user_agent = get_user_agent(request)
if is_desktop(user_agent):
return desktop_response()
else:
return mobile_response()
This code is used to display an image of a desktop or phone below.
Looks like you're browsing on a ...
Desktop!
Your User-Agent (grabbed from the HTTP_USER_AGENT):
CCBot/2.0
This is really just the tip of the iceberg of browser detection. Interesting leads:
- Allowing browsers to force desktop or mobile mode with parameters or cookies
- Checking for the existence of a
X-WAP-PROFILEHTTP headers:X-WAP-PROFILE: http://nds1.nds.nokia.com/uaprof/NN82-1r100.xml
- Checking the contents of the
ACCEPTHTTP header:ACCEPT: text/html,text/css,multipart/mixed,application/java-archive, application/java, application/x-java-archive, text/vnd.sun.j2me.app-descriptor, application/vnd.oma.drm.message, application/vnd.oma.drm.content, application/vnd.oma.dd+xml, application/vnd.oma.drm.rights+xml, application/vnd.oma.drm.rights+wbxml, application/x-nokia-widget, */*
In the end your method of detection depends on your website. Accept the fact that with User-Agent detection logic there will always be some browsers that slip through the cracks. Decide whether it's worse to show a mobile view to your desktop users or a desktop view to your mobile users and try to do the least amount of damage.
Thanks to Rob Manson for the inspiration!
The code is available on GitHub - forks away!
March 31st Update:
This algorithm has been run against the two hundred and thirty two unique User-Agent strings that have so far visited the site. Of those fifteen were actual mobile device User-Agents, all of which were correctly identified by the updated algorithm. Seven non-mainstream bots and scrapers were misidentified as mobile.
Resources:
- MobiForge: A modern switching algorithm
- SmartMOB: Not Device Detection Example Code
- Detect Mobile Browsers
- WURFL: Device Description Repository
View Comments