Selendroid作为一个网络爬虫

15

我打算创建一个 Android 应用程序,实现无头登录到网站并在保持已登录会话的同时从后续页面中爬取一些内容。

最初我在普通的 Java 项目中使用了 HtmlUnit ,它工作得很好。但后来发现 HtmlUnit 与 Android 不兼容。

然后我尝试了通过向登录表单发送 HTTP “POST” 请求的方式来使用 JSoup 库。但由于 JSoup 不支持 JavaScript,导致结果页面不能完全加载。

之后有人建议我看看 Selendroid ,它实际上是一个 Android 测试自动化框架。但我实际上需要的是一个支持 JavaScript 和 Android 的 Html 分析器。我发现 Selendroid 很难理解,甚至找不到要使用哪些依赖项

  • selendroid-client
  • selendroid-standalone
  • selendroid-server

使用 Selenium WebDriver,代码只需要像下面这样简单。但是能否有人给我展示一段类似的 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();

还有,

  1. 我需要在我的Gradle.Build文件中添加哪些依赖?
  2. 我需要导入哪些Selendroid库?
3个回答

2

很遗憾,我没有成功使Selendroid工作。但是,我找到了一个解决方法,可以仅使用带JavaScript启用的Android内置WebView来爬取动态内容。

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);");

   }
});

JS方法document.documentElement.outerHTML将检索加载的URL中包含的完整HTML。然后将检索到的HTML字符串发送到HtmlHandler类中的handleHtml方法。

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

        }
    }

您可以使用像Jsoup这样的库从html字符串中获取必要的内容。

这个解决方案是可行的,但当我尝试在一个有多个重定向的网站上实现它时,即使我比较了URL,重定向也会失败,因为重定向将页面带到并通过相同的URL,我已经使用计数器,但似乎无法知道页面何时完全加载。 - Sujal Mandal

1

我从未使用过Selendroid,所以我对此并不确定,但在网上搜索后,我找到了这个 example ,根据它,我认为你从Selenium翻译到Selendroid的代码应该是:

翻译代码(依我的看法)

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();
    }
  }
}

你的项目需要添加什么

看起来你需要添加 Selendroid 独立的 jar 文件 到你的项目中。如果你不确定如何在 Android 项目中添加外部 jar,可以参考这个问题:如何在 Android 项目中使用外部 JAR 包?

你可以从这里下载 jar 文件jar 文件

此外,仅仅添加 jar 文件 是不够的,你还需要添加与独立版对应版本的 selendroid-client jar 文件

你可以从这里下载它:client jar 文件

希望对你有所帮助!


使用驱动程序是否需要启动/停止Selendroid服务器? - mlz7
正如我在回答中所说,我从未使用过Selendroid,我只是收集所有的信息并组合成一个答案,所以无法确认我所说的是否真实,但看起来似乎是必要的,因为官方页面上写着:运行selendroid-standalone服务器。在这里,您可以找到我看到这个信息的来源和视频演示:http://selendroid.io/mobileWeb.html - Francisco Romero
似乎出现了错误:Error:Execution failed for task ':app:preDexDebug'。
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/bin/java'' finished with non-zero exit value 134
- mlz7
尝试使用以下问题:http://stackoverflow.com/questions/29755160/google-app-engine-gradle-dependency-conflict,https://dev59.com/ZV0b5IYBdhLWcg3wA9Ab,https://dev59.com/B4zda4cB1Zd3GeqPggDp - Francisco Romero
我已经尝试了所有这些解决方案,但都没有成功。 - mlz7
@Steve 也许你应该提出另一个问题来解决这个问题。在SO上搜索你遇到的完整错误,会有很多类似的问题,但是数字不同,当它说:“以非零退出值134完成”。也许有人和你遇到了相同的问题。无论如何,如果我看到一些解决方案,我还会继续为你寻找。 - Francisco Romero

0
我建议您使用WebdriverIO,因为您想要使用Javascript。它使用NodeJs,因此很容易需要其他插件来爬取HTML。
Appium也是一种选择,但更专注于前端测试。

你确定WebdriverIO可以用于Android网页抓取吗? - mlz7
WebDriverIO 肯定可以处理 Android。 - Homewrecker

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