【问题标题】:Selendroid as a web scraperSelendroid 作为网络爬虫
【发布时间】:2015-07-15 12:35:37
【问题描述】:

我打算创建一个 Android 应用程序,该应用程序对网站执行无头登录,然后在保持登录会话的同时从后续页面抓取一些内容。

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

然后我通过向登录表单发送 HTTP“POST”请求来尝试JSoup 库。但是由于 JSoup 不支持 JavaScript,因此生成的页面并没有完全加载。

然后有人建议我查看Selendroid,它实际上是一个 android 测试自动化框架。但我真正需要的是一个同时支持 JavaScript 和 Android 的 Html 解析器。我发现 Selendroid 很难理解,我什至不知道该使用哪个 dependencies

  • selendroid 客户端
  • selendroid-standalone
  • selendroid 服务器

使用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 库?

【问题讨论】:

    标签: android selenium web-scraping selendroid


    【解决方案1】:

    不幸的是,我没有让 Selendroid 工作。但我找到了一种解决方法来抓取动态内容,方法是仅使用 Android 的内置 WebView 并启用 JavaScript。

    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,我使用了计数器但似乎无法确切知道页面何时完全加载。
    【解决方案2】:

    我从来没有用过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 standalone jar file 添加到您的项目中。如果您对如何在 Android 项目中添加外部 jar 有疑问,可以查看以下问题:How can I use external JARs in an Android project?

    这里可以下载jar file:jar file

    此外,似乎仅仅将jar file 添加到您的项目中是不够的。您也应该添加您拥有的独立版本的selendroid-client jar file

    您可以从这里下载:client jar file

    希望对你有帮助!

    【讨论】:

    • 是否需要启动/停止 Selendroid 服务器才能使用驱动程序?
    • 正如我在回答中所说,我从未使用过Selendroid,我只是收集所有信息并将其汇总在一个答案中,因此我无法确认我所使用的说这是真的,但看起来很有必要,正如官方页面所说:Run the selendroid-standalone server。在这里你有我看到这个视频演示的来源:selendroid.io/mobileWeb.html
    • 这似乎引发了错误:错误:任务':app:preDexDebug'的执行失败。 > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: 进程'命令'/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/bin/java''以非零退出值 134 结束
    • 我已经尝试了所有这些解决方案,但都没有成功
    【解决方案3】:

    我建议你使用 WebdriverIO,因为你想使用 Javascript。 它使用 NodeJs,因此很容易需要其他插件来抓取 HTML。

    Appium 也是一种替代方案,但它更侧重于前端测试。

    【讨论】:

    • 你确定 WebdriverIO 可以用于 android web 抓取
    • WebDriverIO 确实可以处理 Android
    猜你喜欢
    • 2023-03-21
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 2012-08-01
    • 2015-05-12
    • 2013-03-29
    相关资源
    最近更新 更多