如何从HTMLUnit中的Javascript链接下载文件

时间:2016-11-22 02:11:26

标签: javascript java htmlunit

正如标题所说,我正在尝试从javascript链接下载带有HTMLUnit的文件。

我开始的页面是https://ppair.uspto.gov/TruePassWebStart/AuthenticationChooser.html。当我在浏览器中单击“使用Java Web Start进行身份验证(新方法)”链接时,会下载.jnlp文件,然后运行该文件以打开要求验证信息的Java程序窗口。验证成功后,原始浏览器窗口会加载包含我将要抓取的信息的页面。

首页的链接源代码段为:

ps -ef | grep node | awk '/'launchPackager.command'/{print $2}' | xargs kill

用于此过程的javascript文件位于https://ppair.uspto.gov/TruePassWebStart/js/WebStart.js。基本上,javascript采用cookie,对其进行编码,并将其附加到URL以请求jnlp文件。我想过只是模仿这个过程,但<tr> <!-- onClick="return launchWebStart('authenticate');" --> <td><a href="javascript:void(0)" id="webstart-authenticate" ><font size="5">Authenticate with Java Web Start (new method)</font></a> </tr> 文件不鼓励这样做。 (他们说“用户通过点击元素并将焦点转移到周围来操纵页面要好得多”,所以我试图这样做。)

我在HTMLUnit中遇到的问题是,在我点击()相应的锚之后,我无法收到预期的jnlp文件。我在本网站的其他问题上尝试了几种不同的东西,包括:

HtmlUnit and JavaScript in linksHtmlUnit to invoke javascript from href to download a file

以下是我使用的代码:

HTMLUnit

从上面的代码中打印出来的是来自起始网页的html而不是预期的jnlp文件。控制台还每3秒从javascript WebConsole打印出状态更新(至少如果我的代码等待时间足够长),所以我知道javascript正在发生一些事情(函数launchWebStart和followMediator是在单独的javascript文件WebStart中的.js):

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;

import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

public class Test {

    public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
        WebClient webClient = new WebClient(BrowserVersion.FIREFOX_45);

        // open starting webpage
        HtmlPage page = webClient.getPage("https://ppair.uspto.gov/TruePassWebStart/AuthenticationChooser.html");

        // id of the element where the link is
        String linkID = "webstart-authenticate";

        // identify the appropriate anchor
        HtmlAnchor anchor = (HtmlAnchor) page.getElementById(linkID);

        // click the anchor
        Page p = anchor.click();

        // get the InputStream for the response; print it out
        InputStream is = p.getWebResponse().getContentAsStream();
        int b = 0;
        while ((b = is.read()) != -1) {
            System.out.print((char)b);
        }
        webClient.close();
    }
}

我也尝试使用downloading files behind javascript button with htmlunit所述的CollectingAttachmentHandler对象:

Nov 21, 2016 2:53:25 PM com.gargoylesoftware.htmlunit.WebConsole info
INFO: launchWebStart

Nov 21, 2016 2:53:25 PM com.gargoylesoftware.htmlunit.WebConsole info
INFO: followMediator

Nov 21, 2016 2:53:25 PM com.gargoylesoftware.htmlunit.WebConsole info
INFO: responseReceived:200
WAIT

Nov 21, 2016 2:53:25 PM com.gargoylesoftware.htmlunit.WebConsole info
INFO: mediatorCallback: next wait

此代码还会打印出起始网页的内容。所以其他解决方案似乎都不适用于我。我无法弄清楚我做错了什么。我已经没有关于如何让它工作的想法(我认为这很容易!)非常感谢任何建议!

1 个答案:

答案 0 :(得分:0)

这是基于您的Test2的有效版本

    WebClient webClient = new WebClient(BrowserVersion.FIREFOX_45);

    // open starting webpage
    HtmlPage page = webClient.getPage("https://ppair.uspto.gov/TruePassWebStart/AuthenticationChooser.html");

    // id of the element where the link is
    String linkID = "webstart-authenticate";

    // identify the appropriate anchor
    HtmlAnchor anchor = (HtmlAnchor) page.getElementById(linkID);

    CountDownLatch latch = new CountDownLatch(1);
    webClient.setWebStartHandler(new WebStartHandler(){

        @Override
        public void handleJnlpResponse(WebResponse webResponse)
        {
            System.out.println("downloading...");
            try (FileOutputStream fos = new FileOutputStream("/Users/Franklyn/Downloads/uspto-auth.authenticate2.jnlp"))
            {
                IOUtils.copy(webResponse.getContentAsStream(),fos);
            } catch (IOException e)
            {
                throw new RuntimeException(e);
            }
            System.out.println("downloaded");
            latch.countDown();
        }
    });

    anchor.click();
    latch.await();//wait downloading to finish

    webClient.close();

那么为什么您的Test2无法正常工作?由于响应的Content-Type对应的下载文件是 application / x-java-jnlp-file ,因此您需要使用 WebStartHandler 。如果响应标头包含名为“ Content-Disposition ”的标头,并且其值以“ attachment ”开头,则您的Test2可能会正常工作。