2

我在网络上看到了一个表格(https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx),如果我给 Select Search Element: as Registration No 和 Enter Search Element: as AP31BF2942 ,如果我点击获取数据按钮,然后我正在获取我的车辆详细信息。
我想在 HttpsURLConnection 中执行此操作。
我在 url 的源代码中看到参数名称为 ctl00$OnlineContent$ddlInput 和 ctl00$OnlineContent$txtInput。

但我无法获得所需的数据。请检查网址

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class TestAPHttp {

private final String USER_AGENT = "Mozilla/5.0";

public static void main(String[] args) throws Exception {

    TestAPHttp http = new TestAPHttp();


    System.out.println("\nTesting  - Send Http POST request");
    http.sendPost();

}



// HTTP POST request
private void sendPost() throws Exception {

    String url = "https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx";
    URL obj = new URL(url);
    HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

    //add reuqest header
    con.setRequestMethod("POST");
    con.setRequestProperty("User-Agent", USER_AGENT);
    con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

    String urlParameters = "ctl00$OnlineContent$ddlInput=R&ctl00$OnlineContent$txtInput=AP31BF2942";

    // Send post request
    con.setDoOutput(true);
    DataOutputStream wr = new DataOutputStream(con.getOutputStream());
    wr.writeBytes(urlParameters);
    wr.flush();
    wr.close();

    int responseCode = con.getResponseCode();
    System.out.println("\nSending 'POST' request to URL : " + url);
    System.out.println("Post parameters : " + urlParameters);
    System.out.println("Response Code : " + responseCode);

    BufferedReader in = new BufferedReader(
            new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

    //print result
    System.out.println(response.toString());

}

}
4

1 回答 1

0

代替

DataOutputStream wr = new DataOutputStream(con.getOutputStream());

它应该读

OutputStream wr = con.getOutputStream();

将字符串转换为byte[]您应该设置编码:

wr.write(urlParameters.getBytes("UTF-8"));

你应该设置Content-Type标题:

con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

顺便说一句,您正在“吃掉”收到的文档的行尾。readLine()读取下一个字符直到行结束,但不会返回\n给您。您应该将它们附加到您的回复中。而且几乎在任何情况下,您都不应该使用StringBuffer, but StringBuilder,但这与这篇文章完全无关,仅供您参考。

编辑

同时,我使用我的 HTTP 客户端库DavidWebb进行了尝试,并设置了一些额外的标头User-Agent,例如所有缺少的表单参数,现在它可以工作了:

Webb webb = Webb.create();
Response<String> response = webb
        .post("https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx")
        .header("User-Agent",
                "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/34.0.1847.116 Chrome/34.0.1847.116 Safari/537.36")
        .header("Accept", "*/*")
        .header("Origin", "https://aptransport.in")
        .header("Referer",
                "https://aptransport.in/CFSTONLINE/Reports/VehicleRegistrationSearch.aspx")
        .header("X-MicrosoftAjax", "Delta=true")
        .param("ctl00$OnlineContent$ddlInput", "R")
        .param("ctl00$OnlineContent$txtInput", "AP31BF2942")
        .param("ctl00$OnlineContent$ScriptManager1",
                "ctl00$OnlineContent$Updatepanel1|ctl00$OnlineContent$btnGetData")
        .param("__EVENTTARGET", "")
        .param("__EVENTARGUMENT", "")
        .param("__VIEWSTATE",
                "/wEPDwUKMTE0MzI5ODM0MGRkdB0g7u2Z+Eg+a4Wr8QLkE1lzgSU=")
        .param("ctl00$OnlineContent$btnGetData", "Get Data")
        .connectTimeout(3000)
        .asString();

if (response.isSuccess()) {
    String result = response.getBody();
    System.out.println(result);
} else {
    System.out.println(response.getStatusCode());
    System.out.println(response.getResponseMessage());
    System.out.println(response.getErrorBody());
}

在许多情况下,模拟浏览器和使用HttpURLConnection不起作用或非常复杂(Cookie、客户端 JavaScript、计时、特殊标头、跨站点请求伪造保护,...)。在您的情况下,您很幸运,但是应用程序中的微小更改可能会在您睡觉时破坏您的工作代码。

那么我是如何解决这个问题的呢?我使用 Chrome 的开发工具(您也可以使用 FireFox、Firebug 等)分析了网络流量(发送的标头和表单数据),但如果是 HTTPS,它应该集成在浏览器中——您无法嗅探 SSL加密流量,wireshark例如

您可以在请求中看到,通过网络发送了更多标头和表单参数:

开发者工具截图

于 2014-05-22T06:41:46.353 回答