2015-05-05 6 views
13

Intendo creare un'applicazione Android che esegua un accesso headless a un sito Web e quindi ritrae alcuni contenuti dalla pagina successiva mantenendo la sessione di accesso.Selendroid come raschiatore web

Per prima cosa ho utilizzato HtmlUnit in un normale progetto Java e ha funzionato perfettamente. Ma in seguito ho scoperto che HtmlUnit non è compatibile con Android.

Quindi ho provato la libreria JSoup inviando la richiesta "POST" HTTP al modulo di accesso. Ma la pagina risultante non viene caricata completamente poiché JSoup non supporterà JavaScript.

Mi è stato quindi suggerito di dare un'occhiata a Selendroid che in realtà è un framework di automazione di test di Android. Ma quello di cui ho realmente bisogno è un parser Html che supporti sia JavaScript che Android. Trovo che Selendroid sia piuttosto difficile da capire e non riesco nemmeno a capire quale dependencies utilizzare.

  • selendroid-client
  • selendroid-alone
  • selendroid server

Con Selenium WebDriver, il codice sarebbe semplice come il seguente. Ma qualcuno può mostrarmi un esempio di codice simile per Selendroid?

WebDriver driver = new FirefoxDriver(); 
    driver.get("https://mail.google.com/"); 

    driver.findElement(By.id("email")).sendKeys(myEmail); 
    driver.findElement(By.id("pass")).sendKeys(pass); 

    // Click on 'Sign In' button 
    driver.findElement(By.id("signIn")).click(); 

E anche,

  1. Cosa dipendenze da aggiungere al mio file Gradle.Build?
  2. Quali librerie Selendroid da importare?

risposta

1

Sfortunatamente non ho usato Selendroid per funzionare. Ma trovo una soluzione alternativa per analizzare il contenuto dinamico usando solo WebView integrato di Android con JavaScript abilitato.

mWebView = new WebView(); 
mWebView.getSettings().setJavaScriptEnabled(true); 
mWebView.addJavascriptInterface(new HtmlHandler(), "HtmlHandler"); 

mWebView.setWebViewClient(new WebViewClient() { 
    @Override 
    public void onPageFinished(WebView view, String url) { 
     super.onPageFinished(view, url); 

     if (url == urlToLoad) { 
     // Pass html source to the HtmlHandler 
     WebView.loadUrl("javascript:HtmlHandler.handleHtml(document.documentElement.outerHTML);"); 

    } 
}); 

Il metodo JS document.documentElement.outerHTML sarà recuperare l'HTML completo contenuta nel URL caricato. Quindi la stringa html recuperata viene inviata al metodo handleHtml nella classe HtmlHandler.

class HtmlHandler { 
     @JavascriptInterface 
     @SuppressWarnings("unused") 
     public void handleHtml(String html) { 
      // scrape the content here 

     } 
    } 

È possibile utilizzare una libreria come Jsoup per analizzare il contenuto necessario dalla stringa html.

+0

Questa soluzione funziona ma quando provo ad implementarla su un sito web con più reindirizzamenti, fallisce anche se confronto gli URL, i reindirizzamenti prendono la pagina e attraverso lo stesso url, ho usato contatori ma non riesco a capire quando esattamente la pagina è completamente caricata. –

0

Suggerisco di utilizzare WebdriverIO poiché si desidera utilizzare Javascript. Usa NodeJs quindi sarà facile richiedere ad altri plugin di carpire l'HTML.

Appium è anche un'alternativa ma è più incentrata sui test front-end.

+0

Sei sicuro che WebdriverIO può essere utilizzato con Android web scraping – Markoe7

+0

WebDriverIO può gestire Android di sicuro – Homewrecker

1

non avevo mai usato Selendroid quindi non sono davvero sicuro di questo, ma la ricerca per la rete ho trovato questo example e, in base ad esso, suppongo che la vostra traduzione del codice Selenium-Selendroid sarebbe:

codice Traduzione (a mio parere)

public class MobileWebTest { 
    private SelendroidLauncher selendroidServer = null; 
    private WebDriver driver = null; 

    @Test 
    public void doTest() { 

    driver.get("https://mail.google.com/"); 

    WebElement email = driver.findElement(By.id("email")).sendKeys(myEmail); 
    WebElement password = driver.findElement(By.id("pass")).sendKeys(pass); 

    WebElement button = driver.findElement(By.id("signIn")).click(); 

    driver.quit(); 
    } 

    @Before 
    public void startSelendroidServer() throws Exception { 
    if (selendroidServer != null) { 
     selendroidServer.stopSelendroid(); 
    } 

    SelendroidConfiguration config = new SelendroidConfiguration(); 

    selendroidServer = new SelendroidLauncher(config); 
    selendroidServer.launchSelendroid(); 

    DesiredCapabilities caps = SelendroidCapabilities.android(); 

    driver = new SelendroidDriver(caps); 
    } 

    @After 
    public void stopSelendroidServer() { 
    if (driver != null) { 
     driver.quit(); 
    } 
    if (selendroidServer != null) { 
     selendroidServer.stopSelendroid(); 
    } 
    } 
} 

Cosa dovete aggiungere al progetto

Sembra che tu debba aggiungere al tuo progetto lo Selendroid standalone jar file. In caso di dubbi su come aggiungere un barattolo esterna in un progetto Android è possibile vedere questa domanda: How can I use external JARs in an Android project?

Qui è possibile scaricare il jar file: jar file

Inoltre, sembra che non è sufficiente solo per aggiungere il jar file al tuo progetto.Dovresti aggiungere anche lo selendroid-client jar file della versione di standalone che hai.

Potete scaricarlo da qui: client jar file

mi aspetto che sarà utile per voi!

+0

è necessario avviare/arrestare il server Selendroid per utilizzare il driver? – Markoe7

+0

Come ho detto nella mia risposta I ** mai ** aveva usato 'Selendroid', raccolgo solo tutte le informazioni e metto insieme una risposta quindi non posso confermare che quello che dico è vero ma sembra che sia necessario, come dice la pagina ufficiale: 'Esegui il server selendroid-standalone'. Qui hai la fonte in cui ho visto questo con un video DEMO: http://selendroid.io/mobileWeb.html –

+0

questo sembra lanciare l'errore: Errore: Esecuzione fallita per task ': app: preDexDebug'. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: processo 'comando' /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/bin/java ' 'finito con valore di uscita diverso da zero 134 – Markoe7

Problemi correlati