提及搜索,你們必定對百度不陌生。每一個搜索引擎後邊都是一個大型爬蟲調度系統。java
第一篇咱們先以百度爲例json
天天都被它爬,今天咱們來爬一下它。數組
url分析服務器
https://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E6%A0%A1%E8%8A%B1
這是上圖的百度圖片地址,咱們能夠在http://www.jsons.cn/urlencode/解碼一下,就是下面這個 url 地址。網絡
能夠看到有不少參數,tn ps ct lm cl nc ie word ,通過測試,咱們發現只有 tn 和 word 是有用參數,簡單化後的url以下:app
直接請求,發現了下面這個問題。
看來咱們簡單的發起網絡請求是不行的。ide
網絡請求工具
咱們知道爬蟲的重要一點就是和網絡請求打交道,並且請求中最重要的就是HTTP協議,首先發起網絡請求。測試
看一下這個 HTTP 工具類,它是 java 原生 HttpURLConnection :ui
package com.javapub.spiderdemo.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; /** * Java原生 HTTP請求 * <p> * 公衆號:JavaPub */ public class HttpClient { public static String doGet(String httpurl) { HttpURLConnection connection = null; InputStream is = null; BufferedReader br = null; String result = null;// 返回結果字符串 try { // 建立遠程url鏈接對象 URL url = new URL(httpurl); // 經過遠程url鏈接對象打開一個鏈接,強轉成httpURLConnection類 connection = (HttpURLConnection) url.openConnection(); // 設置鏈接方式:get connection.setRequestMethod("GET"); // 設置鏈接主機服務器的超時時間:15000毫秒 connection.setConnectTimeout(15000); // 設置讀取遠程返回的數據時間:60000毫秒 connection.setReadTimeout(60000); // 發送請求 connection.connect(); // 經過connection鏈接,獲取輸入流 if (connection.getResponseCode() == 200) { is = connection.getInputStream(); // 封裝輸入流is,並指定字符集 br = new BufferedReader(new InputStreamReader(is, "UTF-8")); // 存放數據 StringBuffer sbf = new StringBuffer(); String temp = null; while ((temp = br.readLine()) != null) { sbf.append(temp); sbf.append("\r\n"); } result = sbf.toString(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉資源 if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } connection.disconnect();// 關閉遠程鏈接 } return result; } public static String doPost(String httpUrl, String param) { HttpURLConnection connection = null; InputStream is = null; OutputStream os = null; BufferedReader br = null; String result = null; try { URL url = new URL(httpUrl); // 經過遠程url鏈接對象打開鏈接 connection = (HttpURLConnection) url.openConnection(); // 設置鏈接請求方式 connection.setRequestMethod("POST"); // 設置鏈接主機服務器超時時間:15000毫秒 connection.setConnectTimeout(15000); // 設置讀取主機服務器返回數據超時時間:60000毫秒 connection.setReadTimeout(60000); // 默認值爲:false,當向遠程服務器傳送數據/寫數據時,須要設置爲true connection.setDoOutput(true); // 默認值爲:true,當前向遠程服務讀取數據時,設置爲true,該參數無關緊要 connection.setDoInput(true); // 設置傳入參數的格式:請求參數應該是 name1=value1&name2=value2 的形式。 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // 設置鑑權信息:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0 connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); // 經過鏈接對象獲取一個輸出流 os = connection.getOutputStream(); // 經過輸出流對象將參數寫出去/傳輸出去,它是經過字節數組寫出的 os.write(param.getBytes()); // 經過鏈接對象獲取一個輸入流,向遠程讀取 if (connection.getResponseCode() == 200) { is = connection.getInputStream(); // 對輸入流對象進行包裝:charset根據工做項目組的要求來設置 br = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuffer sbf = new StringBuffer(); String temp = null; // 循環遍歷一行一行讀取數據 while ((temp = br.readLine()) != null) { sbf.append(temp); sbf.append("\r\n"); } result = sbf.toString(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉資源 if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != os) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } // 斷開與遠程地址url的鏈接 connection.disconnect(); } return result; } }