Java 爬蟲實戰案例三之 HttpClient 詳解
Java 爬蟲實戰案例三之 HttpClient
詳解
1. 程式碼
package httpClient;
import org.apache.http.HttpEntity;
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;
import java.io.IOException;
/**
* 1.this class is used to get a html by HttpClient
*/
public class HelloHttp {
public static void main(String[] args) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault(); //建立httpClient例項
HttpGet httpGet = new HttpGet("http://www.csdn.net"); //建立httpGet例項
CloseableHttpResponse response = httpClient.execute(httpGet);//指向http get請求
HttpEntity entity = response.getEntity();//獲取返回實體
System.out.println("網頁內容:"+ EntityUtils.toString(entity,"utf-8"));//獲取網頁內容
response.close();
httpClient.close();
}
}
2. 執行結果
網頁內容:<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="referrer"content="always">
····
})
</script>
<script src='//csdnimg.cn/pubfooter/js/publib_footer-1.0.3.js?v201807020000' data-isfootertrack="false"></script>
window.csdn.indexSuperise({
smallMoveImg: '//ubmcmm.baidustatic.com/media/v1/0f0002xZEmQ-Pg-yUBISo0.png',
bigMoveImg: '//ubmcmm.baidustatic.com/media/v1/0f0002xZEmU-Pg-yUBISC0.png',
link:'//edu.csdn.net/topic/python115?utm_source=rightpopup',
trackSuperId: 647
});
</script></div></html>
3. 問題
3.1 遮蔽請求
但是問題會隨著請求網址的變化而變化。如果將上述的網址由www.csdb.net
變換成www.tuicool.com
時,就會發現出現如下的執行結果:
網頁內容:<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>系統檢測親不是真人行為,因系統資源限制,我們只能拒絕你的請求。如果你有疑問,可以通過微博 http://weibo.com/tuicool2012/ 聯絡我們。</p>
</body>
</html>
這是因為我們單純使用程式是無法獲取被限制的資源的,那麼該如何解決呢?
解決辦法很簡單,我們只需要在請求httpGet
中新增一個請求頭即可,如下:
httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0");
有人會問,這個 User-Agent
是什麼?這個代表的意思就是:使用的代理使用者,這裡新增上述語句的原因在於,模擬瀏覽器傳送一個請求。這個User-Agent
的值可以在瀏覽器中檢視得到。
接著執行程式得到的結果如下:
網頁內容:<!DOCTYPE HTML>
<!--
______________
< TUICOOL.COM >
--------------
\ ^__^
\ (**)\__$__$__
(__)\ )\/\
U ||------|
|| ||
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="J+HCJtgjgLVvVpjfK4imYYZ1TAQYONE+cMG8aXDYlpEfn6mc0xx2Q/b3/wwm3FPmXFw0sdj4dCerVtH9ZvNYdA==" />
<title>
推酷 - IT人專屬的個性聚合閱讀社群 - 推酷
···
<div style="display:none;">
<script src="https://s22.cnzz.com/stat.php?id=5541078&web_id=5541078" language="JavaScript"></script>
</div>
<script type="text/javascript" src="https://static2.tuicool.com/assets/tip.js?t=3" async></script>
</body>
</html>
如果再更改程式如下:
public static void main(String[] args) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();//建立httpClient例項
HttpGet httpGet = new HttpGet("http://www.tuicool.com"); //建立httpGet例項
httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0");
CloseableHttpResponse response = httpClient.execute(httpGet);//指向http get請求
HttpEntity entity = response.getEntity();//獲取返回實體
System.out.println("Content-Type :"+entity.getContentType());//獲取內容型別
System.out.println("Status : "+response.getStatusLine());//判斷響應狀態
response.close();
httpClient.close();
}
執行結果如下:
其中 Content-Type
表示的是獲取到的實體內容屬於什麼型別;Status
表示的是這個請求的響應狀態是什麼。如果此時將請求地址寫為:http://www.tuicool.com/dsfsd
,再次測試結果如下:
因為這個地址是明顯不存在的,所以請求的 Status
變為了404,但是因為仍然有請求的內容,所以Content-Type
仍然是 text/html
3.2 遮蔽IP
因為部分原因,可能會導致發出請求的主機ip被伺服器的反爬蟲程式監控到,這樣就會導致反爬蟲程式將ip拉入黑名單,如果我們開發的程式再以此ip發出請求時,就會拒絕請求。那麼這個問題該怎麼解決呢?
解決方法很簡單,主要是通過使用代理ip的方式,能夠解決上述問題的方法就是使用“高匿代理”,這是一種代理ip,我們使用此代理ip,就可以實現安全的訪問目標主機了。但是這個“高匿代理”的ip怎麼獲取呢?很簡單,baidu一下即可。如下所示:
從中隨機選擇一個,再修改一下我們的程式碼,如下所示:
public static void main() throws IOException{
CloseableHttpClient httpClient = HttpClients.createDefault();//建立httpClient例項
HttpGet httpGet = new HttpGet("http://www.tuicool.com/"); //建立httpGet例項
HttpHost proxy = new HttpHost("114.235.22.147", 9000);
RequestConfig config = RequestConfig
.custom()
.setProxy(proxy)
.setConnectTimeout(10000)//連線超時
.setSocketTimeout(10000)//讀取超時
.build();
httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0");
CloseableHttpResponse response = httpClient.execute(httpGet);//指向http get請求
HttpEntity entity = response.getEntity();//獲取返回實體
//System.out.println("網頁內容:"+ EntityUtils.toString(entity,"utf-8"));//獲取網頁內容
System.out.println("Content-Type :"+entity.getContentType());//獲取內容型別
System.out.println("Status : "+response.getStatusLine());//判斷響應狀態
response.close();
httpClient.close();
}
執行結果如下: