2013-03-11 7 views
10

Sto cercando un modo per analizzare le stringhe degli user agent per determinare se sono stati generati dai dispositivi mobili. Questo deve essere basato su java e utilizzabile in analisi di file batch di grandi dimensioni su hadoop per generare statistiche (ad esempio, un servizio web non sarebbe appropriato).Rileva i dispositivi mobili dalla stringa dell'agente utente

Ho visto WURFL, ma dato che ho solo bisogno di una risposta binaria mobile/non mobile, il canone di licenza sembra proibitivo.

Finora ho utilizzato UADetector, che è quasi esattamente quello di cui ho bisogno. Tuttavia, ho riscontrato alcune limitazioni. Nel mio test, ho trovato molte stringhe di user agent che forniscono informazioni sufficienti per determinare che l'agente utente provenga da un dispositivo mobile, ma sono segnalate come UNKNOWN da UADetector.

Ad esempio, app Android scarsamente standardizzate possono inviare la stringa UA "Android". Questo è sufficiente per sapere che proviene da un dispositivo mobile, ma UADetector segnala questo UserAgentType come UNKNOWN anziché MOBILE_BROWSER.

Apache Mobile Filter 's Lite Device Detection fa la cosa giusta, ma ho bisogno di qualcosa che posso usare da Java.

Qualcuno può consigliarmi una soluzione migliore?

+1

_ Ad esempio, app Android scarsamente standardizzate possono inviare la stringa UA "Android"._ Non penso che otterrai alcuna libreria che funzioni per user-agent non standard, come impostato dai browser personalizzati. Se sono stringhe personalizzate, sicuramente le possibilità sono infinite? – anotherdave

+0

Mentre è vero che nessuna libreria funziona per tutte le stringhe arbitrarie, "Android" è ancora un frammento di utente-interprete riconosciuto. In effetti le librerie citate nella domanda lo riconoscono come un frammento del sistema operativo; Ad esempio, WURFL segnala che indica un dispositivo mobile. Alcune stringhe di user agent non standard, come "-", non mi aspetterei di ottenere alcuna informazione, ma molte contengono solo informazioni * incomplete *. –

+1

Suppongo che dipenda da cosa hai bisogno/vuoi contare come "mobile". Il sito Lite Device Detection a cui ti sei collegato, ad esempio, conta una stringa UA di 'Android' per essere 'mobile'/'touch' ma non un 'tablet', mentre un'app non standard potrebbe inviare questa stringa UA in una versione tablet facilmente come tramite un telefono. Personalmente, penso che se la tua preoccupazione principale è l'analisi, non mi preoccuperei troppo delle stringhe non standard - stai davvero vedendo un numero abbastanza grande di "SCONOSCIUTI" per influenzare le tue statistiche? – anotherdave

risposta

2

Come leggere il valore del filtro mobile Apache in JSP (per Tomcat)?

Prima nel file httpd.conf in cui è necessario configurare mod_jk si MUSE aggiungere questo:

JkEnvVar AMF_IS_MOBILE undefined 

Il codice Java è:

request.getAttribute("AMF_IS_MOBILE") 

da: http://wiki.apachemobilefilter.org

5

Sono il fondatore e il manutentore del progetto MobileESP, una libreria multipiattaforma open source gratuita per il rilevamento di dispositivi mobili. È ancora molto vivo! :-)

www.mobileesp.org

MobileESP solo dà binario "è mobile" risposte. È possibile rilevare per piattaforma come iOS, Android o Windows Phone o per categoria di dispositivi, come smartphone "iPhone Tier" o tablet. Assicurati di fare una rapida revisione della pagina API.

Come forse sapete, le stringhe useragent variano notevolmente. Se il browser viene spedito sul dispositivo, il produttore può personalizzarlo. Ad esempio, HTC spesso personalizza la stringa useragent del browser Android nativo.

Google fornisce consigli su come l'OEM deve personalizzare l'utente.Se il dispositivo deve essere considerato un telefono, Google consiglia di includere la parola elemento "mobile" nella stringa. Ma se il dispositivo deve essere considerato un tablet, la stringa deve essere non contenere "mobile". L'aderenza a questa raccomandazione varia ampiamente, ovviamente.

I browser di terze parti come Opera o Maxthon possono mettere tutto ciò che vogliono nella stringa useragent - e lo fanno! Alcuni "nuovi" browser che restano senza nome hanno svolto pochissimi lavori di inserimento delle informazioni corrette nelle stringhe useragent di ciascuna piattaforma (ad esempio, versioni Android e iOS). Non c'è molto che puoi fare a meno di ottenere molto traffico da questi browser e desideri investire nel tenere traccia dei loro esatti valori utente per piattaforma e rev. Software.

In ogni caso, MobileESP è stato creato con la visione di eseguire il rilevamento su base pagina per pagina quando viene pubblicata la pagina. Ho intenzionalmente scritto il codice per essere molto facile da leggere e personalizzare.

Per fare l'elaborazione in batch, si potrebbe fare qualcosa di simile:

1.) Nel costruttore, commentare il metodo initDeviceScan(). Non ti servirà per l'elaborazione di massa.

2.) Passare l'oggetto UserAgent e una stringa vuota nel costruttore (UAgentInfo()).

3.) Quindi esegui tutti i metodi di rilevamento a cui sei interessato. Sii attento all'ordine in cui li fai per risparmiare tempo, basato su una scansione dei tuoi utenti.

Ad esempio, se la maggior parte degli utenti è su iPhone e questo è uno dei criteri di rilevamento a cui sei interessato, esegui prima il controllo. Se questo esempio, sicuramente non avresti eseguito prima il metodo BlackBerry!

Le mie informazioni di contatto sono nel codice sorgente e sul sito web. Mandatemi una nota se avete domande o vi imbattete in qualche bug. Sicuramente guardarsi intorno al sito Web MobileESP.org per alcuni suggerimenti.

I migliori auguri per il tuo progetto, Aniket!

  • Anthony
0

Per rilevare iPhone, Android e altri dispositivi mobili in Javauser-agent può essere utilizzato. Se si utilizza Spring, è possibile personalizzare il codice seguente in base alle proprie esigenze.

@Override 
public ModelAndView redirectToAppstore(HttpServletRequest request) { 
    String userAgent = request.getHeader("user-agent").toLowerCase(); 
    String iphoneStoreUrl = "IPONE_STORE_URL"; 
    String androidStoreUrl = "ANDROID_STORE_URL"; 
    if (userAgent.contains("iphone")) 
     return new ModelAndView("redirect:" + iphoneStoreUrl); 
    else if (userAgent.contains("android")) 
     return new ModelAndView("redirect:" + androidStoreUrl); 

    return new ModelAndView("redirect:/"); 
} 
2

51Degrees ha un'API Java open source gratuita che consente di eseguire l'elaborazione offline. Puoi accedervi dal repository GitHub qui. https://github.com/51Degrees/Java-Device-Detection.

Come parte dell'API esiste un esempio di elaborazione non in linea (codice visualizzato anche di seguito), questo prende un file CSV di Agenti utente e restituisce le proprietà richieste in un file di output. Il seguente esempio utilizza solo 3 delle proprietà all'interno del set di dati, per un elenco completo si può guardare il dizionario qui https://51degrees.com/resources/property-dictionary

// output file in current working directory 
public String outputFilePath = "batch-processing-example-results.csv"; 
// pattern detection matching provider 
private final Provider provider; 

/** 
* Initialises the device detection Provider with the included Lite data 
* file. For more data see: 
* <a href="https://51degrees.com/compare-data-options">compare data options 
* </a> 
* 
* @throws IOException if there was a problem reading from the data file. 
*/ 
public OfflineProcessingExample() throws IOException { 
    provider = new Provider(StreamFactory.create(
      Shared.getLitePatternV32(), false)); 
} 

/** 
* Reads a CSV file containing User-Agents and adds the IsMobile, 
* PlatformName and PlatformVersion information for the first 20 lines. 
* For a full list of properties and the files they are available in please 
* see: <a href="https://51degrees.com/resources/property-dictionary"> 
* Property Dictionary</a> 
* 
* @param inputFileName the CSV file to read from. 
* @param outputFilename where to save the file with extra entries. 
* @throws IOException if there was a problem reading from the data file. 
*/ 
public void processCsv(String inputFileName, String outputFilename) 
     throws IOException { 
    BufferedReader bufferedReader = 
      new BufferedReader(new FileReader(inputFileName)); 
    try { 
     FileWriter fileWriter = new FileWriter(outputFilename); 
     try { 
      // it's more efficient over the long haul to create a match 
      // once and reuse it in multiple matches 
      Match match = provider.createMatch(); 
      // there are 20k lines in supplied file, we'll just do a couple 
      // of them! 
      for (int i = 0; i < 20; i++) { 

       // read next line 
       String userAgentString = bufferedReader.readLine(); 

       // ask the provider to match the UA using match we created 
       provider.match(userAgentString, match); 

       // get some property values from the match 
       Values isMobile = match.getValues("IsMobile"); 
       Values platformName = match.getValues("PlatformName"); 
       Values platformVersion = match.getValues("PlatformVersion"); 

       // write result to file 
       fileWriter.append("\"") 
         .append(userAgentString) 
         .append("\", ") 
         .append(getValueForDisplay(isMobile)) 
         .append(", ") 
         .append(getValueForDisplay(platformName)) 
         .append(", ") 
         .append(getValueForDisplay(platformVersion)) 
         .append('\n') 
         .flush(); 
      } 
     } finally { 
      fileWriter.close(); 
     } 
    } finally { 
     bufferedReader.close(); 
    } 
} 

/** 
* Match values may be null. A helper method to get something displayable 
* @param values a Values to render 
* @return a non-null String 
*/ 
protected String getValueForDisplay(Values values) { 
    return values == null ? "N/A": values.toString(); 
} 

/** 
* Closes the {@link fiftyone.mobile.detection.Dataset} by releasing data 
* file readers and freeing the data file from locks. This method should 
* only be used when the {@code Dataset} is no longer required, i.e. when 
* device detection functionality is no longer required, or the data file 
* needs to be freed. 
* 
* @throws IOException if there was a problem accessing the data file. 
*/ 
@Override 
public void close() throws IOException { 
    provider.dataSet.close(); 
} 

/** 
* Instantiates this class and starts 
* {@link #processCsv(java.lang.String, java.lang.String)} with default 
* parameters. 
* 
* @param args command line arguments. 
* @throws IOException if there was a problem accessing the data file. 
*/ 
public static void main(String[] args) throws IOException { 
    System.out.println("Starting Offline Processing Example"); 
    OfflineProcessingExample offlineProcessingExample = 
      new OfflineProcessingExample(); 
    try { 
     offlineProcessingExample.processCsv(Shared.getGoodUserAgentsFile(), 
       offlineProcessingExample.outputFilePath); 
     System.out.println("Output written to " + 
       offlineProcessingExample.outputFilePath); 
    } finally { 
     offlineProcessingExample.close(); 
    } 
} 

Spero che questo aiuti.

Divulgazione: lavoro a 51 gradi.

Problemi correlati