java - Android Web Scraping con un navegador sin cabeza
selenium web-scraping (1)
He pasado un día investigando una biblioteca que se puede usar para lograr lo siguiente:
- Recupere el contenido completo de una página web como en el fondo sin mostrar el resultado a una vista.
- La lib debería admitir páginas que disparan solicitudes ajax para cargar algunos datos de resultados adicionales después de que el HTML inicial se haya cargado, por ejemplo.
- Del html resultante necesito agarrar elementos en forma de selector xpath o css.
- En el futuro, posiblemente también necesite navegar a una página siguiente (eventos de apagado, envío de botones / enlaces, etc.)
Esto es lo que he intentado sin éxito:
- Jsoup: Funciona muy bien, pero no es compatible con javascript / ajax (por lo que no carga la página completa)
- Android incorporado en HttpEntity: el mismo problema con javascript / ajax como jsoup
- HtmlUnit: parece exactamente lo que necesito pero después de horas no puedo hacer que funcione en Android (otros usuarios fallaron al tratar de cargar los archivos jar de 12MB +. Yo mismo cargué el código fuente completo y lo mencioné como una biblioteca de proyectos solo para encontrar eso cosas como Applets y java.awt (utilizadas por HtmlUnit) no existen en Android).
- Rhino: encuentro esto muy confuso y no sé cómo hacerlo funcionar en Android, incluso si es lo que estoy buscando.
- Selenium Driver: parece que puede funcionar, pero no tiene una forma directa de implementarlo de forma anónima para que no se muestre el html real a la vista.
Realmente quiero que HtmlUnit funcione, ya que parece ser el más adecuado para mi solución. ¿Hay alguna forma o al menos otra biblioteca que he perdido que sea adecuada para mis necesidades?
Actualmente estoy usando Android Studio 0.1.7 y puedo moverme a Ellipse si es necesario.
¡Gracias por adelantado!
Ok, después de 2 semanas admito la derrota y estoy usando una solución alternativa que funciona bien para mí en este momento.
El problema:
Es muy difícil portar HTMLUnit a Android (o al menos con mi nivel de experiencia). Estoy seguro de que es un proyecto que vale la pena (y no tanto tiempo para el programador java experimentado). Envié un correo electrónico a los chicos de HTMLUnit y me comentaron que no están buscando en un puerto o qué esfuerzo estarán involucrados, pero sugirieron que cualquiera que quiera comenzar con un proyecto así debería enviar un mensaje a su lista de correo para involucrar a más desarrolladores ( http://htmlunit.sourceforge.net/mail-lists.html ).
La solución alternativa:
Utilicé Android WebView incorporado y superé el método onPageFinished de la clase Webview para inyectar Javascript que capture todo el html después de que la página se haya cargado por completo. Webview también se puede usar para invocar acciones de JavaScript posteriores, hacer clic en botones, rellenar formularios, etc.
Código:
webView.getSettings().setJavaScriptEnabled(true);
MyJavaScriptInterface jInterface = new MyJavaScriptInterface(context);
webView.addJavascriptInterface(jInterface, "HtmlViewer");
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
//Load HTML
webView.loadUrl("javascript:window.HtmlViewer.showHTML
(''<head>''+document.getElementsByTagName(''html'')[0].innerHTML+''</head>'');");
}
webView.loadUrl(StartURL);
ParseHtml(jInterface.html);
public class MyJavaScriptInterface {
private Context ctx;
public String html;
MyJavaScriptInterface(Context ctx) {
this.ctx = ctx;
}
@JavascriptInterface
public void showHTML(String _html) {
html = _html;
}
}