Understanding Devices That Browse Your Website


6/20/2013 12:01 PM

Device Detection Java Python PHP Development

Understanding what devices are browsing your website and their capabilities is key to optimising your website for mobile. I have put together some small code examples showing how you can detect mobile devices and features using 51Degrees.mobi, allowing you to fully optimise your mobile users web experience.

Understanding screen size

The following sample shows how we can log a request, the date of said request and also the device's screen dimensions in Java, PHP and Python. This will enable you to then tailor your web experience to a specific set of screen sizes based on the knowledge returned.


String fileDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); String filePath = String.format("logfiles/Simple_Log_%s.csv", fileDate); String date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()); String uri = request.getRequestURI(); String screenInchesWidth = super.getProperty(request, "ScreenInchesWidth"); String screenInchesHeight = super.getProperty(request, "ScreenInchesHeight"); FileWriter fw = new FileWriter(date, true); fw.write(String.format("%s %s %s %s \r\n", date, uri, screenInchesWidth, screenInchesHeight)); fw.close();


require_once('51degrees.mobi.php'); $file_path = dirname(__FILE__) . '/Simple_Log_' . date('Y-m-d') . '.csv'; $date = date('c'); $uri = $_SERVER['REQUEST_URI']; $screen_inches_width = $_51d['ScreenInchesWidth']; $screen_inches_height = $_51d['ScreenInchesHeight']; file_put_contents($file_path, "$date, $uri, $screen_inches_width, $screen_inches_height \r\n", FILE_APPEND);


from datetime import date from fiftyone_degrees import mobile_detector d = date.today() file_path = "Simple_Log_{}.csv".format(d.strftime("%Y-%m-%d")) log_date = d.strftime("%Y-%m-%d'T'%H:%M:%S") # useragent is the requesting device's useragent string device = mobile_detector.match(useragent) screen_inches_width = device.properties['ScreenInchesWidth'] screen_inches_height = device.properties['ScreenInchesHeight'] # uri is url requested with open(file_path, "a") as log_file: log_file.write("{} {} {} {} \r\n".format(log_date, uri, screen_inches_width, screen_inches_height)

These logs are basic examples of gaining information about a device and logging it. This idea can be extended to save more device properties or to persist data in other ways, such as a database.

Backlog information

If you have not been storing logs with device properties when the request was originally made, do not worry as you can use 51Degrees Device Data to understand properties of devices browsing your website from the useragent alone.

The following code will create a Java, Python or C console program that can be supplied at the location of a 'space seperated' log file and a column number indicating where the useragent is. The program will then print the number of entries parsed and the average screen size in sizes.


package console; import fiftyone.mobile.detection.*; import fiftyone.mobile.detection.binary.BinaryException; import fiftyone.mobile.detection.binary.Reader; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class Console { public static void main(String[] args) throws IOException, BinaryException { // The number of devices read from the log file. int count = 0; // The column in the input file the user agent is held in. int column = Integer.parseInt(args[1]); // Screen dimension variables. double total = 0, width, height, squareInches; // Create a provider to determine the device capabilities. Provider provider = Reader.create("51Degrees.mobi.dat"); // Read each line of the log file provided in argument 0. // Assume the value at column 8 is the UserAgent string. //FileInputStream reader = new FileInputStream(args[0]); BufferedReader reader = new BufferedReader(new FileReader(args[0])); String line = reader.readLine(); while (line != null) { String[] values = line.split(" "); if (values.length >= column) { // Get the device information based on the UserAgent. BaseDeviceInfo device = provider.getDeviceInfo( values[column - 1].replace("+", " ")); if (device != null) { // Determine the screen dimensions in inches. try { width = Double.parseDouble(device.getFirstPropertyValue("ScreenInchesWidth")); height = Double.parseDouble(device.getFirstPropertyValue("ScreenInchesHeight")); squareInches = width * height; // If valid values are available (not a desktop/laptop) // then add the values to the results. if (squareInches > 0) { total += squareInches; count++; } } catch (NumberFormatException ex) { // Sizes could not be converted. Do nothing. } } } } System.out.println(String.format("Average screen size '%d' square inches from '%d' devices", total / count, count)); System.in.read(); } }


import sys; from fiftyone_degrees import mobile_detector # column of useragent given in second argument column = sys.int(argv[1]) count = 0 total = 0 # open log file, with path supplied in first argument logs = open( sys.argv[0], "r" ) for log in logs: values = log.split(' ') if(len(values) >= column) : device = mobile_detector.match(values[column - 1]) if(device != None) : try: width = float(device.properties['screenInchesWidth']) height = float(device.properties['screenInchesHeight']) squareInches = width * height; if(squareInches > 0) : count += 1 total += squareInches except ValueError: # sizes could not be converted. Do nothing. print "Average screen size '{}' square inches from '{}' devices".format(total / count, count)


#include <stdio.h> #include <stdlib.h> #include <string.h> #include "51Degrees.mobi.h" // first arg is the file path of the log // second arg is the useragent column // third arg is the file path of trie data int main(int argc, char* argv[]) { int column = atoi(argv[2]); int count = 0; int total = 0; char buffer[500]; char output[100]; FILE *fp = fopen(argv[1], "r"); printf("Loading trie data."); int res = init(argv[3], "ScreenInchesWidth,ScreenInchesHeight"); if(res == 0) { while (!feof(fp)) { // load line into buffer fgets(buffer, 500, fp); char *ua; ua = strtok(buffer," "); //int i; for(int i = 0; i < column - 1; i++) { ua = strtok(NULL, " "); } // replace + with space int pos = 0; while(ua[pos] != '\0') { if(ua[pos] == '+') { ua[pos] = ' '; } pos++; } int offset = getDeviceOffset(ua); processDeviceCSV(offset , output, 100); printf("%s", output); // throwaway parts that only say the property name strtok(output, "|"); char * widthProp = strtok(NULL, "\n"); int width = atoi(widthProp); strtok(NULL, "|"); char* heightProp = strtok(NULL, "\n"); int height = atoi(heightProp); int screenInches = width * height; if(screenInches > 0) { total += screenInches; count++; } } if(count > 0) { printf("Average screen size '%d' square inches from '%d' devices.", total / count, count); } else { printf("No devices read."); } } else { printf("Data could not be initialised."); } scanf("%s"); return res; }

The C program utilises the trie detection routine, which is a much faster detection method but comes at the expense of a larger data file.

Knowledge is power

Once you have information on which devices are browsing your web page you can understand how best to optimise your website for mobile.

You will be able to understand not only which devices are browsing your website, but also which pages they are most likely to navigate to. Using this knowledge will help you create a great mobile web experience for your users.

51Degrees Device Detection is fast, accurate and updated weekly by a professional data team.