【问题标题】:Download a file process by server, with HtmlUnit通过服务器下载文件进程,使用 HtmlUnit
【发布时间】:2021-03-10 22:23:41
【问题描述】:

我想自动进行文件转换: https://www.gpsvisualizer.com/map_input?form=googleearth。 我的问题是,gpsvisualizer 允许独立转换,但我有 500 个文件要转换。 所以我使用 hmtlUnit 来自动化这个过程。

感谢以下代码,我可以修改“选择”,例如:

  1. “输出文件类型”
  2. “添加 DEM 高程数据”

上传我的文件并获取重定向的 html 页面的 url,我可以在其中下载想要的文件。

我的问题是我找不到下载文件的方法。

有人有建议吗?

提前谢谢。

这是我的代码:

    WebClient webClient = new WebClient();
    webClient.getOptions().setCssEnabled(false);
    webClient.getOptions().setJavaScriptEnabled(true);
    webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
    webClient.getOptions().setThrowExceptionOnScriptError(false);
    webClient.getOptions().setRedirectEnabled(true);
    
    

    //fetching the web page
    String url = "https://www.gpsvisualizer.com/map_input?form=googleearth";
    //String url = "https://www.reddit.com/r/scraping/";
    HtmlPage page = webClient.getPage(url);
    
    System.out.println(page.getUrl());
    
    System.out.println(page.getTitleText());
    
    //Select set .kml file
    HtmlSelect selectFileType = (HtmlSelect) page.getElementByName("googleearth_zip");
    System.out.println(selectFileType.getOption(0).asText());
    //System.out.println(selectFileType.getOption(1).asText());
    
    HtmlOption kmlFile = selectFileType.getOptionByText(".kml (uncompressed)");
    System.out.println(kmlFile.asText());
    selectFileType.setSelectedAttribute(kmlFile, true);
    
    //Select add elevation on file
    HtmlSelect selectelevation = (HtmlSelect) page.getElementByName("add_elevation");
    System.out.println(selectelevation.getOption(4).asText());
    
    HtmlOption europeSRTM1 = selectelevation.getOptionByText("NASA SRTM1 (30m res., NoAm, Europe, more)");
    System.out.println(europeSRTM1.asText());
    selectelevation.setSelectedAttribute(europeSRTM1, true);
    
    //add file
    HtmlForm myForm = page.getFormByName("main");
    HtmlFileInput fileInput = myForm.getInputByName("uploaded_file_1");
    fileInput.setValueAttribute("/media/Stock/Projets/Suratram/Ressources/Traces_WS/puissance/kml_files/01_douce-signoret.kml");
    HtmlElement submitBtn = page.getElementByName("submitted");
    
    //page google
    HtmlPage page2 = submitBtn.click();
    System.out.println(page2.getUrl());

【问题讨论】:

    标签: java web web-scraping htmlunit


    【解决方案1】:

    因为我没有样例文件,所以只能给出一些一般性的建议

    HtmlUnit 对于下载有点奇怪——一般来说它是这样工作的:

    • 没有下载 - 每个响应都加载到一个窗口中; HtmlUnit 替换当前窗口的内容或使用 UnknownPage 创建一个新窗口,使内容可作为流使用。新窗口的决定是根据内容类型(以及其他一些因素,例如锚点的目标)来完成的。根据经验,如果实际浏览器显示此下载对话框,您可以在新窗口中下载。

    这是什么意思 - 我猜您的页面将返回被 HtmlUnit 检测为单独下载的内容。您可以向 WebClient 询问可用的窗口(webClient.getWebWindows()),并且在提交/单击之后可能会有一个新窗口(如果异步 js 是游戏的一部分,您可能需要添加一些等待)。这个新窗口将包含一个 UnknownPage 作为封闭页。并且可以向未知页面询问类似这样的响应

    Page newPage = newbWin.getEnclosedPage(); // UnknownPage inside window
    WebResponse newResponse = newPage.getWebResponse();
    try ...                            
        IOUtils.copy(newResponse.getContentAsStream(), outStream);
    catch...
    

    作为替代方案,您可以实现一个 WebWindowListener(必须在客户端注册),以便在创建新窗口时收到通知。

    希望对您有所帮助,如果您需要更多信息,请在 github 上打开一个问题,并提供您的输入文件和代码,以便我重现您的案例。

    【讨论】:

    • 感谢您的回答,我继续使用 htmlUnit 并了解下载文件并非如此。感谢 htmlUnit,我可以使用所需的参数设置页面并上传我的文件。之后,网站会使用转换后的文件向新页面收费,我可以在其中下载它。使用 htmlUnit,我找到了打开的 html 页面,转换后的文件在哪里。最后,我的问题是我找不到从这个新页面下载文件的方法。
    • 再次,请在 github 上打开一个问题并提供您的代码以及所有必需的输入,我将尝试向您展示如何获取该文件。 HtmlUnit 真的可以做到这一点。
    • 你好,抱歉很久了,我终于在gitHub上开了一个issue。
    【解决方案2】:

    这是我的问题的答案。

    按照 HtmlUnit 的文档,我在尝试将下载页面转换为“Webwindow”对象时遇到问题。

    HtmlPage page = webClient.getPage(uri);
    WebWindow window = page.getEnclosingWindow();
    

    所以最后,我不需要将其转换为“Webwindow”。 只是为了解析“Anchors”以找到我的并捕获“webResponse”以获取已处理的文件。

    您可以在以下位置找到更多详细信息: https://github.com/HtmlUnit/htmlunit/issues/352

    感谢 RBRi 的帮助。

    最好的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 2014-08-25
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多