Java爬蟲技術之HttpClient學習筆記
第一節、HttpClient
一、HttpClient 簡介
超文本傳輸協議【The Hyper-Text Transfer Protocol (HTTP)】是當今互聯網上使用的最重要(significant)的協議,
越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。
雖然在 JDK 的 java net包中已經提供了訪問 HTTP 協議的基本功能,但是對於大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。
HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,並且它支持 HTTP 協議最新的版本和建議。
官方站點:http://hc.apache.org/
最新版本:http://hc.apache.org/httpcomponents-client-4.5.x/
官方文檔:http://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/index.html
二、Maven依賴包
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
三、HttpClient的 HelloWorld 實現
package com.guo.httpclient; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; importorg.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class HelloWorld { public static void main(String args[]){ // 創建httpClient實例 CloseableHttpClient httpClient=HttpClients.createDefault(); //創建httpGet實例 HttpGet httpGet=new HttpGet("https://www.cnblogs.com/"); CloseableHttpResponse response=null; //定義個返回信息 try { response=httpClient.execute(httpGet); } catch (ClientProtocolException e) {//http協議異常 // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { //io異常 // TODO Auto-generated catch block e.printStackTrace(); }//執行http get請求 // 獲取返回信息 實體 HttpEntity entity=response.getEntity(); try { System.out.println("獲取網頁內容"+EntityUtils.toString(entity, "utf-8"));//獲取網頁內容 } catch (ParseException e) { //解析異常 // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { response.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { httpClient.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
這節講的是直接請求的 沒有模擬瀏覽器 有些網站爬不了
下節將解決這個問題
如果爬國內網站 將上述代碼的try catch去掉,拋出異常就行了
第二節、模擬瀏覽器抓取(以火狐瀏覽器為例)
有的網站設置反扒,上節的直接請求會出現如下問題
這就需要模擬瀏覽器來查詢
一:設置請求頭消息 User-Agent 模擬瀏覽器
1.請求頭消息
打開一個網站,這裏以www.tuicool.com 為例 按F12點網絡
看請求頭信息,是瀏覽器發送給目標服務器看的,目標服務器進行識別,如下圖
怎麽模擬瀏覽器?
用HttpGet實例 調用 setHeader方法 設置頭信息給目標服務器看的,代碼如下
二:獲取響應內容類型 Content-Type
獲取用HttpEntity 的實體調用getContent-Type方法, 響應內容是鍵值對,這裏我們getValue獲取value值,代碼如下
這裏將獲取網頁內容註釋掉,只輸出響應內容信息
運行結果如下
這個帶編碼的utf-8,有的是不帶編碼的,這是根據服務器設置的
為什麽要獲取響應內容的類型呢?
因為我們在采集的時候,會有很多鏈接,要過濾掉一些無關緊要的信息
三:獲取響應狀態 Status
200 正常 403 拒絕 500 服務器報錯 404 未找到頁面
前面響應的都很順利,響應狀態為200 如下
要獲取響應狀態,用CloseableHttpResponse 實例 調用getStatusLine方法,代碼如下
這裏我們只要狀態200 就行了,所以加個getStatusCode方法,只獲取狀態碼
第三節、HttpClient 抓取圖片
先用上章講的ContentType 獲取下類型,代碼如下
顯示結果為image/jpeg 圖片類型,如下
現在將這個圖片放到本地,(也可以放到服務器上)
這裏HttpEntity實體調用個getContent方法 這個方法是InputStream 輸入流類型的,所以返回InputStream,先判斷entity不為空
獲取到了InputStream 輸入流實例,要怎麽將圖片復制到本地
用傳統的方法
略
簡單點的話,用阿帕奇封裝好的commons.io
首先maven引入jar包,然後編寫代碼如下
但實際開發你怎麽知道是.jpg的後綴呢?開發時將地址http://xxx.com/xxx.xx 點後面的xx獲取到,再拼接到保存文件。
第四節 代理IP
用髙匿代理
百度搜索代理IP,
用HttpGet實例 調用 setConfig方法。
具體項目中 寫個小爬蟲爬 代理ip的網站 ,只需爬前十個代理ip,放到隊列中。
第五節 鏈接及讀取超時
一、HttpClient連接時間
是HttpClient發送請求的地方開始到連接上目標url主機地址的時間,理論上是距離越短越快。
HttpClient的默認連接時間是1分鐘,假如超過1分鐘 過一會繼續嘗試連接。
如果一個url總是連不上,會影響其他線程的線程進去,所以我們有必要進行設置。
比如設置10秒鐘 假如10秒鐘沒有連接上 我們就報錯。用log4j日誌記錄相關信息。
二、HttpClient讀取時間
是HttpClient已經連接到了目標服務器,然後進行內容數據的獲取,一般情況 讀取數據都是很快速的,
如果讀取的數據量大,或是目標服務器本身的問題(比如讀取數據庫速度慢,並發量大等等)會影響讀取時間。
還是需要設置,比如設置10秒鐘 假如10秒鐘還沒讀取完,就報錯
Java爬蟲技術之HttpClient學習筆記