通过服务器下载文件过程,使用 HtmlUnit

Download a file process by server, with HtmlUnit

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

感谢以下代码,我能够修改“select”,例如:

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

因为没有样例文件,所以只能给一些大概的建议

HtmlUnit 对于下载有点奇怪 - 通常它是这样工作的:

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

这是什么意思 - 我猜您的页面将 return 被 HtmlUnit 检测为单独下载的内容。您可以向 WebClient 询问可用的 windows (webClient.getWebWindows()) 并且 submit/click 之后可能会有一个新的(如果 async js 是其中的一部分,则可能需要添加一些等待游戏)。这个新的 window 将包含一个 UnknownPage 作为 enclosePage。你可以向未知页面询问类似于此的响应

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

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

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

这是我的问题的答案。

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

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

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

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

感谢 RBRi 的帮助。

最佳