1. 程式人生 > >Java爬蟲技術之HttpClient學習筆記

Java爬蟲技術之HttpClient學習筆記

結果 小爬蟲 如果 依賴包 很多 tac world 官方 靈活

第一節、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;
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去掉,拋出異常就行了

第二節、模擬瀏覽器抓取(以火狐瀏覽器為例)

有的網站設置反扒,上節的直接請求會出現如下問題

技術分享圖片

這就需要模擬瀏覽器來查詢

一:設置請求頭消息 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學習筆記