關於URL接口中數據的獲取問題

從URL中獲取數據

Java中發起的POST請求,接收URL中的數據。

拿到的接口不能直接訪問,會被攔截。

需要在header中加入發佈接口時,提供的串碼(key-value的形式),即可獲取到數據。

HTTPClient的使用方式:

使用HttpClient發送請求、接收響應很簡單,一般需要如下幾步即可。

 

1. 創建HttpClient對象。

2. 創建請求方法的實例,並指定請求URL。如果需要發送GET請求,創建HttpGet對象;如果需要發送POST請求,創建HttpPost對象。

3. 如果需要發送請求參數,可調用HttpGet、HttpPost共同的setParams(HetpParams params)方法來添加請求參數;對於HttpPost對象而言,也可調用setEntity(HttpEntity entity)方法來設置請求參數。

4. 調用HttpClient對象的execute(HttpUriRequest request)發送請求,該方法返回一個HttpResponse。

5. 調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。

6. 釋放連接。無論執行方法是否成功,都必須釋放連接

參考鏈接:http://blog.csdn.net/sunhuaqiang1/article/details/51751581

 

 

使用到了Apache提供的commons-httpclient  jar包,在pom中的依賴:

<dependency>

                     <groupId>commons-httpclient</groupId>

                     <artifactId>commons-httpclient</artifactId>

                     <version>3.1</version>

              </dependency>

提供一個查詢各種jar包依賴關係的網址:http://mvnrepository.com

示例代碼:

public String transRequest(String url, String type, String message) {

  // 響應內容

  String result = "";

  // 定義http客戶端對象--httpClient

  HttpClient httpClient = new HttpClient();

  

  // 定義並實例化客戶端鏈接對象-postMethod

  PostMethod postMethod = new PostMethod(url);

  

  try{

   // 設置http的頭

   postMethod.setRequestHeader("ContentType",

     "application/x-www-form-urlencoded;charset=UTF-8");

 

   // 填入各個表單域的值

   NameValuePair[] data = { new NameValuePair("type", type),

     new NameValuePair("message", message) };

  

   // 將表單的值放入postMethod中

   postMethod.setRequestBody(data);

 

   // 定義訪問地址的鏈接狀態

   int statusCode = 0;

   try {

    // 客戶端請求url數據

    statusCode = httpClient.executeMethod(postMethod);

   } catch (Exception e) {

    e.printStackTrace();

   }

  

   // 請求成功狀態-200

   if (statusCode == HttpStatus.SC_OK) {

    try {

     result = postMethod.getResponseBodyAsString();

    } catch (IOException e) {

     e.printStackTrace();

    }

   } else {

    log.error("請求返回狀態:" + statusCode);

   }

  } catch (Exception e) {

   log.error(e.getMessage(), e);

  } finally {

   // 釋放鏈接

   postMethod.releaseConnection();

   httpClient.getHttpConnectionManager().closeIdleConnections(0);

  }

  return result;

 }

 

使用此種方法可以得到POST中的數據信息。

但是在實際開發中,需要在header中加串碼,保證數據的安全性,如果不加串碼,訪問會被攔截。

實現代碼如下:

public String getURLInfo(){

String result = "";

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        String nowTime = sdf.format(new Date());

        String url = "http://10.161.**.**:**/ checkDate=" + nowTime;

           

            //定義http客戶端對象,定義並實例化客戶端連接對象。

        HttpClient httpClient = new HttpClient();

        PostMethod postMethod = new PostMethod(url);

 

        try {

            postMethod.setRequestHeader(headerName , headerValue);

            int statusCode = 0;

            try {

                //客戶端請求url中的數據。返回請求結果的狀態碼。

                statusCode = httpClient.executeMethod(postMethod);

            }catch (Exception e){

                e.printStackTrace();

            }

             //如果狀態碼=200。表示請求成功。

            if(statusCode == HttpStatus.SC_OK){   

                try {

                    result = postMethod.getResponseBodyAsString();

                }catch (Exception e){

                    e.printStackTrace();

                }

            }else{

                System.out.println("請求有誤,錯誤代碼:"+ statusCode);

            }

        }catch (Exception e){

            System.out.println(e.getMessage());

        }finally {

            //釋放鏈接。

            postMethod.releaseConnection();

            httpClient.getHttpConnectionManager().closeIdleConnections(0);

        }

    return result;

}

得到url中數據的字符串形式。一般是一個JSON格式的字符串。之後需要對字符串做什麼處理,截取或者強轉都可以。

 

 

org.json和net.sf.json的區別

net.sf.json.JSONObject 和org.json.JSONObject  的差別。

 

一、創建json對象

String str = "{\"code\":\"0000\", \"msg\":{\"availableBalance\":31503079.02}}

 

org.json.JSONObject:

JSONObject json = new JSONObject(str);

 

net.sf.json.JSONObject:

JSONObject json = JSONObject.fromObject(str); 

 

net.sf.json.jsonobject 沒有 new JSONObject(String)的構造方法

 

二、解析json

 

第一種直接用json對象.getXXX();方法獲取

 

net.sf.json.JSONObject: 沒有嚴格要求獲取字段的類型跟getXXX()的類型一樣

org.json.JSONObject:獲取的字段類型必須跟getXXX()的類型一樣

 

e.g.

JSONObject msgObj = json.getJSONObject("msg");

 

String availableBalance = msgObj.getString("availableBalance");

 

如果在org.json.JSONObject 就會報錯,可以msgObj.getDouble("availableBalance");也不會丟精度;而net.sf.json.JSONObject正確,但是精度會丟失,如果String str = "{\"code\":\"0000\", \"msg\":{\"availableBalance\":\"31503079.02\"}}";

就不會丟失精度。

 

第二中json對象直接轉變實體對象

 

public class BalanceDto {

private String availableBalance;

public String getAvailableBalance() {

return availableBalance;

}

public void setAvailableBalance(String availableBalance) {

this.availableBalance = availableBalance;

}

public String toString(){

 

return "availableBalance   "+availableBalance;

}

 

 

}

org.json.JSONObject:

 

BalanceDto alanceDto  = (BalanceDto) JSONObject.stringToValue(msgObj);

 

這個句話編譯通過,但是運行會報錯,原因是BalanceDto 類中availableBalance 的類型跟json中的“availableBalance ”類型不同意

 

net.sf.json.JSONObject:

 

String msg = json.getString("msg");

BalanceDto  alanceDto = (BalanceDto) JSONObject.toBean(

msg, new BalanceDto().getClass());

 

三、從json中獲取數組

 

JSONArray subArray = json.getJSONArray("msg");

 

net.sf.json.JSONObject:

int leng = subArray.size();

 

org.json.JSONObject:

int leng = subArray.length();

 

HTTP之常見狀態碼

1xx:指示信息--表示請求已接收,繼續處理

2xx:成功--表示請求已被成功接收、理解、接受

3xx:重定向--要完成請求必須進行更進一步的操作

4xx:客戶端錯誤--請求有語法錯誤或請求無法實現

5xx:服務器端錯誤--服務器未能實現合法的請求

 

200 OK                        //客戶端請求成功

400 Bad Request               //客戶端請求有語法錯誤,不能被服務器所理解

401 Unauthorized              //請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用

403 Forbidden                 //服務器收到請求,但是拒絕提供服務

404 Not Found                 //請求資源不存在,eg:輸入了錯誤的URL

500 Internal Server Error     //服務器發生不可預期的錯誤

503 Server Unavailable        //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常

 

更多狀態碼及含義:http://www.runoob.com/http/http-status-codes.html

 

下載某URL中的圖片

此種方法沒有定位某些圖片的功能,但是可以下載到圖片。

package com.fly.test;

 

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import org.jsoup.nodes.Element;

import org.jsoup.select.Elements;

import org.junit.Test;

 

import java.io.*;

import java.net.URL;

import java.net.URLConnection;

import java.nio.charset.Charset;

 

/**

 * @Description :

 * @Create by FLY on 2017-11-02  14:56

 */

public class DemoDownloadPicture {

 

    String ALL_URL_STR = "";

    String ALL_SRC_STR = "";

    int nonameId = 1;

    int record = 0;

    int noPicname = 0;

 

    @Test

    public void start(){

        //要爬取的網站地址

        String urlStr = "http://cpu.baidu.com/wap/1022/1329713/detail/4970306611472452/news?blockId=2998&foward=block";

        String html = getHTML(urlStr);

        getURL(html,0,"E://crawler//pic");      //圖片存放地址,若無需創建

    }

 

    public String getHTML(String urlStr){

        StringBuilder html = new StringBuilder();

        BufferedReader buffer = null;

        try {

            URL url = new URL(urlStr);

            URLConnection conn = url.openConnection();

            conn.connect();

 

            buffer = new BufferedReader(new InputStreamReader(conn.getInputStream(), Charset.forName("UTF-8")));

            String line = null;

            while((line = buffer.readLine()) != null){

                html.append(line);

            }

 

        }catch (Exception e){

            e.printStackTrace();

        }finally {

            if(buffer != null){

                try {

                    buffer.close();

                }catch (Exception e){

                    throw new RuntimeException("關閉流錯誤");

                }

            }

        }

        return html.toString();

    }

 

    public void getURL(String html, int tmp,String fileName){

        if(tmp > 5 || html == null || html.length() == 0){

            System.out.println("--------end-------");

            return;

        }

 

        if(record > 1000){

            System.out.println("--------圖片大於1000張-----");

            return;

        }

 

        System.out.println("------start----------");

 

         String urlMain = "http://cpu.baidu.com/wap/1022/1329713/detail/4970306611472452/news?blockId=2998&foward=block";

         String urlPicMain = "http:";

 

        //解析網頁內容

        Document doc = Jsoup.parse(html);

        //獲取圖片的鏈接,並下載圖片。

        Elements imglinks = doc.select("img[src]");

        int picnum = 0;

        String dirFileName = "";

        for(Element imglink : imglinks){

            String src = imglink.attr("src");

            if(src == null ||"".equals(src) || src.length() < 3){

                continue;

            }

            if(!ALL_SRC_STR.contains(src)){

                ALL_SRC_STR += src + " ## ";

                if(!src.contains(urlPicMain)){

                    src = urlPicMain + src;

                }

                if(picnum == 0){

                    //創建新目錄

                    dirFileName  = makedir(fileName);

                    picnum ++ ;

                }

                record ++;

                downloadPicture(src , dirFileName);

            }

        }

        Elements links = doc.select("a");

        for(Element link : links){

            String href = link.attr("href");

            String text = link.text();

            if(href == null || "".equals(href) || href.length() > 3){

                continue;

            }

            if(text == null || "".equals(text)){

                text = "noName" + nonameId ++;

            }

            if(!href.contains(urlMain)){

                href = urlMain + href;

            }

            //distinct

            if(!ALL_URL_STR.contains(href)){

                ALL_URL_STR += href + " ## ";

                System.out.println("***********");

                System.out.println("獲取到新的url地址"+text+"--->"+href);

                getURL(getHTML(href) , tmp ++ ,text);

            }

        }

        return;

    }

 

    public void downloadPicture(String src,String fileName){

        InputStream is = null;

        OutputStream os = null;

        try {

            String imageName = src.substring(src.lastIndexOf("/")+1,src.length());

            int index = src.lastIndexOf(".");

            String imgType = ".png";

            System.out.println(index);

            if(index != 1){

                imgType = src.substring(index+1,src.length());

                if(imgType.length() > 5){

                    imgType = ".png";

                }

            }

            if(imageName == null || imageName.length() == 0){

                imageName = ""+ noPicname++ ;

            }

            imageName += imgType;

           

            //連接URL

            URL url = new URL(src);

            URLConnection uri = url.openConnection();

            is = uri.getInputStream();

            os = new FileOutputStream(new File(fileName,imageName));

           

            byte[] buf = new byte[1024];

            int length = 0;

            while((length = is.read(buf, 0,buf.length)) != -1){

                os.write(buf,0,length);

            }

            os.close();

            is.close();

            System.out.println(src + "下載成功=====");

        }catch (Exception e){

            System.out.println(src + "下載失敗=====");

        }finally {

            try {

                if(os != null){

                    os.close();

                }

                if(is != null){

                    is.close();

                }

            }catch (IOException e){

                System.out.println("關閉流時發生異常");

            }

        }

    }

 

    public String makedir(String filesName){

        //定義文件夾路徑

        String fileParh = "E://crawler//pic//"+filesName;

        File file = new File(fileParh);

        if(!file.exists()&&!file.isDirectory()){

            file.mkdirs();//創建文件夾

            if(file.exists()&&file.isDirectory()){

                System.out.println("文件夾創建成功");

                return fileParh;

            }else{

                System.out.println("文件夾創建不成功");

                return "E://crawler//pic";

            }

        }

        else{

            System.out.println(filesName + "文件已經存在");

            return fileParh;

        }

    }

}

 

只獲取需要的圖片

獲取URL中指定的圖片,獲取源代碼中圖片的URL。組成json形式,在解析時,導入json文件。未完待續···

 

 

 

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