Question

I have a PNR Inquiry app on Google Play. It was working very fine. But recently Indian Railwys added captcha to their PNR Inquiry section and because of this I am not able to pass proper data to the server to get proper response. How to add this captcha in my app in form of an imageview and ask the users to enter captcha details also so that I can send proper data and get proper response.

Indian Railways PNR Inquiry Link

enter image description here

Was it helpful?

Solution

If you check the html code, its actualy pretty bad captcha. Background of captcha is: http://www.indianrail.gov.in/1.jpg Those numbers are actualy in input tag:

<input name="lccp_cap_val" value="14167" id="txtCaptcha" type="hidden">

What they are doing is, via javascript, use numbers from that hidden input tag and put them on that span with "captcha" background.

So basicaly your flow is:

  • read their html

  • get "captcha" (lol, funny captcha though) value from input field

  • when user puts data in your PNR field and presses Get Status

  • post form field, put PNR in proper value, put captcha in proper value

  • parse response

Oh yeah, one more thing. You can put any value in hidden input and "captcha" input, as long as they are the same. They aren't checking it via session or anything.

EDIT (code sample for submiting form): To simplify posting form i recommend HttpClient components from Apache: http://hc.apache.org/downloads.cgi Lets say you downloaded HttpClient 4.3.1. Include client, core and mime libraries in your project (copy to libs folder, right click on project, properties, Java Build Path, Libraries, Add Jars -> add those 3.).

Code example would be:

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

Also, be warned i didn't wrap this in async call, so you will have to do that.

OTHER TIPS

Image from the network can be displayed in android via efficient image loading api's like Picasso/volley or simply image view via async task.

considering all above things as basic build a logic such that you should need a image URL for that captcha if user resets or refresh the captcha it should reload new image via network call requesting the new request implementation, you have to get REST api access to the Indian railway and check in that any image uri available in that (it may be in base64 format )

if REST API is not available you may think of building your own server with this code

RESTful API to check the PNR Status

pnrapi

Update: you don't need to do this complex hacks , just implement Drago's answer !

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top