使用无头浏览器进行Android网络爬虫

36

我花了一天的时间研究一个库,可以用来完成以下任务:

  • 后台获取网页的全部内容,而不需要呈现结果给用户。
  • 该库应支持在初始HTML加载后触发AJAX请求以加载一些附加结果数据的页面。
  • 从结果HTML中,我需要以xpath或css选择器形式抓取元素。
  • 将来我还可能需要导航到下一页(触发事件,提交按钮/链接等)

以下是我尝试但未成功的方法:

  • Jsoup:效果很好,但不支持JavaScript/ajax(因此它不会加载完整的页面)
  • Android内置HttpEntity:与Jsoup相同,无法处理JavaScript/ajax
  • HtmlUnit:看起来非常符合我的需求,但经过几个小时的尝试仍不能在Android上运行(其他用户试图加载12MB+的jar文件也失败了。我自己加载了完整的源代码,并将其作为项目库引用,结果发现HtmlUnit使用的Applets和java.awt并不存在于Android中)。
  • Rhino-我认为这很令人困惑,不知道如何在Android上使用它,即使它就是我正在寻找的。
  • Selenium Driver:看起来可以工作,但您没有直接实现以无头方式进行操作的简单方式,以便不会将实际HTML显示给用户。

我真的希望HtmlUnit能够正常工作,因为它似乎最适合我的解决方案。有没有办法或者至少是我忽略了的另一个库,适合我的需求?

我目前使用的是Android Studio 0.1.7,如果需要可以切换到Ellipse。

提前感谢!


1
似乎没有适用于我的情况的东西。我已经开始为HTMLUnit开发Android端口,并希望很快能有一些可用的东西。我会尽快发布一个HtmlUnit分支,供任何人下载。希望我能让HtmlUnit开发人员参与进来,因为似乎有很多人对Android端口感兴趣。 - Pierre
3
四年了,我们仍在这里!我仍然面临着同样的问题! - mehulmpt
根据当前的答案,这个问题应该被重新表述,不要让它成为一个库请求。然后它就可以被重新打开了。如果你重新表述了它,请@Makyen通知我,这样我就可以帮助你重新打开它。 - Makyen
3
HTMLUnit Android端口的链接: https://github.com/HtmlUnit/htmlunit-android - Cyber Avater
1
HTMLUnit现在已经支持Android啦:https://github.com/HtmlUnit/htmlunit-android - thebluepandabear
显示剩余3条评论
2个回答

37

好的,经过两周的尝试后,我承认失败了,目前正在使用一个对我来说非常有效的解决方法。

问题:
将HTMLUnit移植到Android上实在太困难了(或者至少对我这个水平的人是这样)。我相信这是一个值得做的项目(对于有经验的Java程序员来说不会太费时间)。我给HTMLUnit的开发人员发了电子邮件,他们回复说他们没有考虑过移植的事情及其所需的努力,但建议任何想启动这样一个项目的人应该发送消息到他们的邮件列表中以吸引更多开发人员加入(http://htmlunit.sourceforge.net/mail-lists.html)。

解决方法:
我使用android内置的WebView,并重写了Webview类的onPageFinished方法,以注入JavaScript代码,在页面完全加载后获取所有的HTML内容。WebView还可以用于调用其他的javascript操作,如点击按钮、填写表单等。

代码:

webView.getSettings().setJavaScriptEnabled(true);
MyJavaScriptInterface jInterface = new MyJavaScriptInterface();
webView.addJavascriptInterface(jInterface, "HtmlViewer");

webView.setWebViewClient(new WebViewClient() {

    @Override
    public void onPageFinished(WebView view, String url) {
       //Load HTML
       webView.loadUrl("javascript:window.HtmlViewer.showHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
    }

}

webView.loadUrl(StartURL);
ParseHtml(jInterface.html);   

public class MyJavaScriptInterface {

    public String html;

    @JavascriptInterface
    public void showHTML(String _html) {
        html = _html;
    }
}

我也想创建一个安卓应用程序,但是在继续之前我需要先爬取网站,而且该网站还启用了JavaScript(动态加载),有什么建议吗?谢谢! - ZdaR
5
这个问题仍未得到解决,为Android开发的HTMLUnit端口将是一个梦想,因为你可以从页面中获取元素并运行 .click() 方法生成新页面,是否有任何方法可以使用 Android WebView 来实现这一点? - Sujal Mandal
手机在待机状态下,这个能工作吗? - LUKER
@LUKER,你找到答案了吗? - PascalVKooten
Retrofit怎么样?有人试过吗?https://github.com/square/retrofit - ninjaxelite

0
我已经采用了上述提到的实现方式(注入JavaScript),并且它对我很有效。我所做的就是将Webview的可见性设置为在其他UI元素下隐藏。我也考虑过使用selenium来实现同样的效果。我已经在Python中使用Chrome和selenium,效果非常好,但正如你所提到的,不易不显示浏览器窗口。但我认为在Android中可能有可能只是不显示组件。我需要尝试一下。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接