從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文件。未完待續···
|