2014-01-20 27 views
7

我在Google Play上有一個PNR查詢應用程序。它工作得很好。但最近Indian Railwys在他們的PNR查詢部分添加了驗證碼,因此我無法將正確的數據傳遞給服務器以獲得正確的響應。如何在我的應用程序中以圖像視圖的形式添加此驗證碼,並要求用戶輸入驗證碼詳細信息,以便我可以發送正確的數據並獲得適當的響應。如何更新印度鐵路站點中添加的PNR Capcha

Indian Railways PNR Inquiry Link

這裏是我的PnrCheck.java我較早使用。請幫助應該在這裏做了什麼修改..

import java.io.BufferedReader; 
import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.Socket; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 

import org.apache.http.Header; 
import org.apache.http.HttpHost; 
import org.apache.http.HttpResponse; 
import org.apache.http.HttpVersion; 
import org.apache.http.entity.InputStreamEntity; 
import org.apache.http.impl.DefaultHttpClientConnection; 
import org.apache.http.message.BasicHttpEntityEnclosingRequest; 
import org.apache.http.params.BasicHttpParams; 
import org.apache.http.params.HttpParams; 
import org.apache.http.params.HttpProtocolParams; 
import org.apache.http.protocol.BasicHttpContext; 
import org.apache.http.protocol.BasicHttpProcessor; 
import org.apache.http.protocol.ExecutionContext; 
import org.apache.http.protocol.HttpContext; 
import org.apache.http.protocol.HttpRequestExecutor; 
import org.apache.http.protocol.RequestConnControl; 
import org.apache.http.protocol.RequestContent; 
import org.apache.http.protocol.RequestExpectContinue; 
import org.apache.http.protocol.RequestTargetHost; 
import org.apache.http.protocol.RequestUserAgent; 
import org.apache.http.util.EntityUtils; 

public class PNRStatusCheck { 
    public static void main(String args[]) { 
     try { 
      String pnr1 = "1154177041"; 
      String reqStr = "lccp_pnrno1=" + pnr1 + "&submitpnr=Get+Status"; 
      PNRStatusCheck check = new PNRStatusCheck(); 
      StringBuffer data = check.getPNRResponse(reqStr, "http://www.indianrail.gov.in/cgi_bin/inet_pnrstat_cgi.cgi"); 
      if(data != null) { 
       @SuppressWarnings("unused") 
       PNRStatus pnr = check.parseHtml(data); 
      } 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public StringBuffer getPNRResponse(String reqStr, String urlAddr) throws Exception { 
     String urlHost = null; 
     int port; 
     String method = null; 
     try { 
      URL url = new URL(urlAddr); 
      urlHost = url.getHost(); 
      port = url.getPort(); 
      method = url.getFile(); 

      // validate port 
      if(port == -1) { 
       port = url.getDefaultPort(); 
      } 
     } catch(Exception e) { 
      e.printStackTrace(); 
      throw new Exception(e); 
     } 

     HttpParams params = new BasicHttpParams(); 
     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, "UTF-8"); 
     HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1"); 
     HttpProtocolParams.setUseExpectContinue(params, true); 

     BasicHttpProcessor httpproc = new BasicHttpProcessor(); 
     // Required protocol interceptors 
     httpproc.addInterceptor(new RequestContent()); 
     httpproc.addInterceptor(new RequestTargetHost()); 
     // Recommended protocol interceptors 
     httpproc.addInterceptor(new RequestConnControl()); 
     httpproc.addInterceptor(new RequestUserAgent()); 
     httpproc.addInterceptor(new RequestExpectContinue()); 

     HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); 
     HttpContext context = new BasicHttpContext(null); 
     HttpHost host = new HttpHost(urlHost, port); 
     DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); 

     context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); 
     context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host); 
     @SuppressWarnings("unused") 
     String resData = null; 
     @SuppressWarnings("unused") 
     String statusStr = null; 
     StringBuffer buff = new StringBuffer(); 
     try { 
      String REQ_METHOD = method; 
      String[] targets = { REQ_METHOD }; 

      for (int i = 0; i < targets.length; i++) { 
       if (!conn.isOpen()) { 
        Socket socket = new Socket(host.getHostName(), host.getPort()); 
        conn.bind(socket, params); 
       } 
       BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST", targets[i]); 
       req.setEntity(new InputStreamEntity(new ByteArrayInputStream(reqStr.toString().getBytes()), reqStr.length())); 
       req.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
       req.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7"); 
       req.setHeader("Cache-Control", "max-age=0"); 
       req.setHeader("Connection", "keep-alive"); 
       req.setHeader("Origin", "http://www.indianrail.gov.in"); 
       req.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); 
       req.setHeader("Referer", "http://www.indianrail.gov.in/pnr_Enq.html"); 
       //req.setHeader("Accept-Encoding", "gzip,deflate,sdch"); 
       req.setHeader("Accept-Language", "en-US,en;q=0.8"); 
       req.setHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3"); 


       httpexecutor.preProcess(req, httpproc, context); 

       HttpResponse response = httpexecutor.execute(req, conn, context); 
       response.setParams(params); 
       httpexecutor.postProcess(response, httpproc, context); 

       Header[] headers = response.getAllHeaders(); 
       for(int j=0; j<headers.length; j++) { 
        if(headers[j].getName().equalsIgnoreCase("ERROR_MSG")) { 
         resData = EntityUtils.toString(response.getEntity()); 
        } 
       } 
       statusStr = response.getStatusLine().toString(); 
       InputStream in = response.getEntity().getContent(); 
       BufferedReader reader = null; 
       if(in != null) { 
        reader = new BufferedReader(new InputStreamReader(in)); 
       } 

       String line = null; 
       while((line = reader.readLine()) != null) { 
        buff.append(line + "\n"); 
       } 
       try { 
        in.close(); 
       } catch (Exception e) {} 
      } 
     } catch (Exception e) { 
      throw new Exception(e); 
     } finally { 
      try { 
       conn.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     return buff; 
    } 

    public PNRStatus parseHtml(StringBuffer data) throws Exception { 
     BufferedReader reader = null; 
     if(data != null) { 
      reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(data.toString().getBytes()))); 
     } else { 
      return null; 
     } 

     String line = null; 
     TrainDetails trainDetails = new TrainDetails(); 
     List<PassengerDetails> passDetailsList = new ArrayList<PassengerDetails>(); 
     PassengerDetails passDetails = null; 
     int i = 0; 
     while ((line = reader.readLine()) != null) { 
      if(line.startsWith("<TD") && line.contains("table_border_both")) { 
       line = line.replace("<B>", ""); 
       line = line.substring(line.indexOf("\">")+2, line.indexOf("</")).trim(); 

       if(line.contains("CHART")) { 
        trainDetails.setChatStatus(line); 
        break; 
       } 
       if(i > 7) {//Passenger Details 
        if(passDetails == null) { 
         passDetails = new PassengerDetails(); 
        } 
        switch(i) { 
        case 8 : 
         passDetails.setName(line); 
         break; 
        case 9 : 
         passDetails.setBookingStatus(line.replace(" ", "")); 
         break; 
        case 10 : 
         passDetails.setCurrentStatus(line.replace(" ", "")); 
         i = 7; 
         break; 
        } 
        if(i == 7) { 
         passDetailsList.add(passDetails); 
         passDetails = null; 
        } 

       } else { // Train details 
        switch(i){ 
        case 0 : 
          trainDetails.setNumber(line); 
          break; 
        case 1 : 
          trainDetails.setName(line); 
          break; 
        case 2 : 
          trainDetails.setBoardingDate(line); 
          break; 
        case 3 : 
          trainDetails.setFrom(line); 
          break; 
        case 4 : 
          trainDetails.setTo(line); 
          break; 
        case 5 : 
          trainDetails.setReservedUpto(line); 
          break; 
        case 6 : 
          trainDetails.setBoardingPoint(line); 
          break; 
        case 7 : 
          trainDetails.setReservedType(line); 
          break; 
        default : 
         break; 
        } 
       } 
       i++; 
      } 
     } 

     if(trainDetails.getNumber() != null) { 
      PNRStatus pnrStatus = new PNRStatus(); 
      pnrStatus.setTrainDetails(trainDetails); 
      pnrStatus.setPassengerDetails(passDetailsList); 
      return pnrStatus; 
     } else { 
      return null; 
     } 
    } 

} 
+0

有沒有人試過看到這個問題。? – ZooZ

回答

1

我發現了一個帖子,詢問同這樣的回答:

如果檢查HTML代碼,其actualy非常糟糕的驗證碼。驗證碼的背景是:http://www.indianrail.gov.in/1.jpg這些數字actualy輸入標籤:

他們是做什麼的,通過JavaScript,從隱藏的輸入標籤使用號碼,並把它們與「驗證碼」背景跨度。

所以basicaly你的流程是:

閱讀他們的HTML

GET「驗證碼」(笑,有趣的驗證碼雖然)從輸入字段值

當用戶將數據在您的PNR外地和壓力機得到狀態

後表單域,把PNR中應有的價值,把驗證碼在適當的值

解析響應

噢,還有一件事。只要它們相同,您可以在隱藏輸入和「驗證碼」輸入中輸入任何值。他們沒有通過會話或任何其他方式檢查它。編輯(提交表單的代碼示例):爲了簡化發佈表單,我推薦Apache使用HttpClient組件:http://hc.apache.org/downloads.cgi可以說你下載了HttpClient 4.3.1。在您的項目中包含客戶端,核心和mime庫(複製到libs文件夾,右鍵單擊項目,屬性,Java Build Path,庫,添加Jars - >添加那些3)。

代碼示例:

private static final String FORM_TARGET = "http://www.indianrail.gov.in/cgi_bin/inet_pnstat_cgi.cgi"; 
private static final String INPUT_PNR = "lccp_pnrno1"; 
private static final String INPUT_CAPTCHA = "lccp_capinp_val"; 
private static final String INPUT_CAPTCHA_HIDDEN = "lccp_cap_val"; 

private void getHtml(String userPnr) { 
    MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
    builder.addTextBody(INPUT_PNR, userPnr); // users PNR code 
    builder.addTextBody(INPUT_CAPTCHA, "123456"); 
    builder.addTextBody("submit", "Get Status"); 
    builder.addTextBody(INPUT_CAPTCHA_HIDDEN, "123456"); // values don't 
                  // matter as 
                  // long as they 
                  // are the same 

    HttpEntity entity = builder.build(); 

    HttpPost httpPost = new HttpPost(FORM_TARGET); 
    httpPost.setEntity(entity); 

    HttpClient client = new DefaultHttpClient(); 

    HttpResponse response = null; 
    String htmlString = ""; 
    try { 
     response = client.execute(httpPost); 
     htmlString = convertStreamToString(response.getEntity().getContent()); 
       // now you can parse this string to get data you require. 
    } catch (Exception letsIgnoreItForNow) { 
    } 
} 

private static String convertStreamToString(InputStream is) { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
    StringBuilder sb = new StringBuilder(); 

    String line = null; 
    try { 
     while ((line = reader.readLine()) != null) { 
      sb.append(line); 
     } 
    } catch (IOException ignoredOnceMore) { 
    } finally { 
     try { 
      is.close(); 
     } catch (IOException manyIgnoredExceptions) { 
     } 
    } 

    return sb.toString(); 
} 

另外,被警告我沒有AsyncTask調用把這個包,所以你必須做到這一點。

2

如果你正確的頁面上點擊並查看源http://www.indianrail.gov.in/pnr_Enq.html,你會發現的功能,生成驗證碼源,比較驗證碼和驗證它:

有一個javascript函數帽子繪製驗證碼:

//Generates the captcha function that draws the captcha 
function DrawCaptcha() 
    {  
    var a = Math.ceil(Math.random() * 9)+ ''; 
    var b = Math.ceil(Math.random() * 9)+ '';  
    var c = Math.ceil(Math.random() * 9)+ ''; 
    var d = Math.ceil(Math.random() * 9)+ ''; 
    var e = Math.ceil(Math.random() * 9)+ ''; 

    var code = a + b + c + d + e; 
    document.getElementById("txtCaptcha").value = code; 
    document.getElementById("txtCaptchaDiv").innerHTML = code; 
} 

//Function to checking the form inputs: 

function checkform(theform){ 
    var why = ""; 

    if(theform.txtInput.value == ""){ 
    why += "- Security code should not be empty.\n"; 
    } 
    if(theform.txtInput.value != ""){ 
     if(ValidCaptcha(theform.txtInput.value) == false){ //here validating the captcha 
      why += "- Security code did not match.\n"; 
     } 
    } 
    if(why != ""){ 
     alert(why); 
     return false; 
    } 
} 

// Validate the Entered input aganist the generated security code function 
function ValidCaptcha(){ 
    var str1 = removeSpaces(document.getElementById('txtCaptcha').value); 
    var str2 = removeSpaces(document.getElementById('txtInput').value); 
    if (str1 == str2){ 
     return true; 
    }else{ 
     return false; 
    } 
} 

// Remove the spaces from the entered and generated code 
function removeSpaces(string){ 
    return string.split(' ').join(''); 
} 

,而不是使用URL http://www.indianrail.gov.in/cgi_bin/inet_pnrstat_cgi.cgi另外,儘量網址:http://www.indianrail.gov.in/cgi_bin/inet_pnstat_cgi_28688.cgi。前一個是失敗。我認爲它已經改變了。 希望這可以幫助你。

+0

我很抱歉,但我是Android新手。你能告訴我如何處理這些功能嗎?在我提供的代碼中編輯什麼?? – ZooZ

+0

第二個想法是,你是否首先嚐試並使用新的URL?另外就我所見,驗證碼似乎是本地的。他們不會將它發送到服務器或任何地方。首先嚐試並更新您的網址。 –

+0

只需一分鐘。我會檢查並更新會發生什麼.. – ZooZ