如何在Java HtmlUnit中作为多部分POST请求的一部分发送图片

4

我正在尝试使用Java将验证码提交到decaptcher.com。 Decaptcher并没有真正解释如何使用他们的API,因此我正在尝试弄清楚如何使用HTTP POST请求提交验证码。以下是我从他们的网站上获得的示例代码:

<form 
 method="post" 
 action="http://poster.decaptcher.com/" 
 enctype="multipart/form-data">
 <input type="hidden" name="function"  value="picture2">
 <input type="text"   name="username"  value="client">
 <input type="text"   name="password"  value="qwerty">
 <input type="file"   name="pict">
 <input type="text"   name="pict_to"   value="0">
 <input type="text"   name="pict_type" value="0">
 <input type="submit" value="Send">
</form>

我需要向Web服务器发送如下的POST请求,并获取返回给我的字符串。以下是我在Java中实现的尝试。

public String getDecaptcherAnswer(String username, String password){
        try{
            URL decaptcherPostURL = new URL("http://poster.decaptcher.com/");
            WebRequestSettings request = new WebRequestSettings(decaptcherPostURL, HttpMethod.POST);
            request.setEncodingType(FormEncodingType.MULTIPART);
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new NameValuePair("function", "picture2"));
            params.add(new NameValuePair("username", username));
            params.add(new NameValuePair("password", password));

            //I added this block in 
            File file = new File("captcha.png");
            params.add(new KeyDataPair("pict", capFile, "png", "utf-8"));
            //----------------------

            params.add(new NameValuePair("pict_to", "0"));
            params.add(new NameValuePair("pict_type", "0"));
            request.setRequestParameters(params);
            request.setUrl(decaptcherPostURL);

            HtmlPage page = webClient.getPage(request);
            System.out.println(page.asText());
            System.out.println("--------------------------------------");
            System.out.println(page.asXml());

            return page.asText();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
}

我应该将pict的值设置为一个文件对象,而不是指向验证码存储位置的字符串吗?(captcha.png是我要提交的图片的名称)。
3个回答

3

有一个更高级的机制可以发送该文件,您不需要创建 WebRequestSettings 并设置其各个值。

您应该将静态 HTML 托管在某个地方,然后执行以下操作。

如果您仍然遇到问题,请在 HtmlUnit bug 追踪器中提交错误报告。

顺便说一下,HtmlUnit 2.8 即将发布,请试用一下。

WebClient webClient = new WebClient();
HtmlPage page = webClient.getPage("http://some_host/test.html");
HtmlForm form = page.getForms().get(0);
form.getInputByName("username").setValueAttribute(username);
form.getInputByName("password").setValueAttribute(password);
form.getInputByName("pict_to").setValueAttribute("0");
form.getInputByName("pict_type").setValueAttribute("0");
form.getInputByName("pict").setValueAttribute("full_path_to_captcha_png");
form.<HtmlFileInput>getInputByName("pict").setContentType("image/png");//optional
HtmlPage page2 = form.getInputByValue("Send").click();

1
是的,HtmlUnit旨在为您减轻烦恼:),请使用2.8版本进行测试。 - Ahmed Ashour

1

在这种情况下,您不应该使用 NameValuePair,而是应该使用它的子类 KeyDataPair。这样您就可以指定要上传的文件。

以下代码应该可以正常工作:

new KeyDataPair("pict", new File(fileName), "image/png", "utf-8");

内容类型参数是文件的MIME类型。由于您正在上传PNG文件,因此应该是image/png


我应该将KeyValuePair声明为: - Dylan
//假设我从“captcha.png”创建了一个名为file的File对象 新的KeyValuePair(“pict”,文件,“png”,“utf-8”)PNG文件是否使用UTF-8编码? - Dylan
我已经做出了必要的更改,但现在从网站返回一个超时错误。我认为这意味着我的请求正常工作,因为之前我什么都没有得到,但我不知道为什么请求会超时。 - Dylan
另外,@Ahmed,charset 不是指文件编码吗? - Dylan
@Dylan,HtmlUnit的当前实现会按照页面设置发送字符集,如果你持有不同意见,请在HtmlUnit跟踪器中提交最小测试案例的错误报告。 - Ahmed Ashour
显示剩余3条评论

0
这是我想要输入的内容:
File file = new File("captcha.png");
params.add(new KeyDataPair("pict", capFile, "png", "utf-8"));

PNG文件是否使用UTF-8编码?这是我如何为文件输入指定KeyDataPair的方式吗?我认为我要么指定了错误的contentType,要么指定了错误的charSet,或者两者都错了。我应该把它们都大写吗?


2
这不应该是一个单独的答案。你应该将它作为编辑添加到你的原始问题中。 - Justian Meyer

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