Java爬取12306餘票

  一、前言

  

  今年國慶和中秋一起放,雖然很歡快,但是沒有票了!!!

  於是自己倒騰了一個查詢餘票的小程序。

 

  二、準備工作

   

  1、先打開12306的頁面

  

  2、然後右鍵檢查,點network

  

  3、再點一下12306頁面上的查詢,就可以看到發起了ajax請求

  

  4、點第一個,很明顯是json串,這樣就方便很多

  

  5、複製第二個的鏈接

 

  

  比如我這裏就是:

      https://kyfw.12306.cn/otn/leftTicket/queryX?leftTicketDTO.train_date=2017-10-01&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=NJH&purpose_codes=ADULT

 

  三、開始工作

 

   這是通過HttpURLConnection來發起一個請求,裏面的網址就填準備工作裏面複製的那串

  /**
     * 發起一個http請求
     */
    public static void sendHttp(){
        URL url;
        int responsecode;
        HttpURLConnection urlConnection;
        BufferedReader reader;
        String line;
        try{
            //忽略Ssl(針對12306)
            SslUtils.ignoreSsl();
            //生成一個URL對象
            url=new URL("這裏填你要訪問的網址");
            /**
             * 這是爲了防止12306對同一ip多次訪問進行限制
             * 這裏填的ip是暫時有效的,想要獲取更多就得自己去找 搜索代理ip
             */
            System.getProperties().setProperty("proxySet", "true");
            System.setProperty("http.proxyHost", "120.78.15.63");  
            System.setProperty("http.proxyPort", "80"); 
            //打開URL
            urlConnection = (HttpURLConnection)url.openConnection();
            //僞造一個請求頭 一般網頁不用,有些網站會看你有沒有請求頭,比如 12306......
            urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0"); 
            urlConnection.setRequestProperty("Host","kyfw.12306.cn");
            urlConnection.setRequestProperty("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            urlConnection.setRequestProperty("Accept-Language","zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
            urlConnection.setRequestProperty("Accept-Encoding","identity");
            urlConnection.setRequestProperty("Connection","keep-alive");
            urlConnection.setRequestProperty("Upgrade-Insecure-Requests","1");
            //獲取服務器響應代碼
            responsecode=urlConnection.getResponseCode();
            //假如響應代碼爲200,就是代表成功
            if(responsecode==200){
                reader=new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),"UTF-8"));
                while((line=reader.readLine())!=null){
                    System.out.println(line);//在這裏幹你想幹的事情
                }
            }else{
                System.out.println("獲取不到網頁的源碼,服務器響應代碼爲:"+responsecode);
            }
        }catch(Exception e){
            System.out.println("獲取不到網頁的源碼,出現異常:"+e);
        }
    }

   

  跑這個方法之前還需要用到一個類,是用來忽略12306的證書問題

package domain;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SslUtils {

    public static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[1];
        TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }

    static class miTM implements TrustManager,X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }

        public void checkClientTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }
    }


    public static void ignoreSsl() throws Exception{
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }
}

 

  然後跑一下這個方法,看到獲取到了json

  

 

 

  就可以對這串字符串爲所欲爲了,嘿嘿嘿

 

 

  四、最後

   

  一般查到餘票都是發郵件,不會JavaMail的可以看我另一篇博客,開箱即用。

 

  轉載需標註原文地址!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章