標籤:The cat 調用 get 設定 protoc 建議 alt 擷取網頁內容
第一節、HttpClient
一、HttpClient 簡介
超文字傳輸通訊協定 (HTTP)【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;import org.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去掉,拋出異常就行了
第二節、類比瀏覽器抓取(以Firefox瀏覽器為例)
有的網站設定反扒,上節的直接請求會出現如下問題
這就需要類比瀏覽器來查詢
一:佈建要求頭訊息 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學習筆記