爬蟲(chóng)要想爬取需要的信息,首先第一步就要抓取到頁(yè)面html內(nèi)容伞插,然后對(duì)html進(jìn)行分析号阿,獲取想要的內(nèi)容斟珊。上一篇隨筆《Java爬蟲(chóng)系列一:寫(xiě)在開(kāi)始前》中提到了HttpClient可以抓取頁(yè)面內(nèi)容写妥。
今天就來(lái)介紹下抓取html內(nèi)容的工具:HttpClient拳球。
一、什么是HttpClient
度娘說(shuō):
HttpClient 是Apache Jakarta Common 下的子項(xiàng)目珍特,可以用來(lái)提供高效的祝峻、最新的、功能豐富的支持 HTTP 協(xié)議的客戶端編程工具包扎筒,并且它支持 HTTP 協(xié)議最新的版本和建議呼猪。
以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細(xì)的功能可以參見(jiàn) HttpClient 的官網(wǎng):
(1)實(shí)現(xiàn)了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
(2)支持自動(dòng)轉(zhuǎn)向
(3)支持 HTTPS 協(xié)議
(4)支持代理服務(wù)器等
這里面提到了官網(wǎng)砸琅,那就順便說(shuō)下它官網(wǎng)上的一些東西。
根據(jù)百度給出的HomePage是這個(gè):http://hc.apache.org/httpclient-3.x/轴踱,但是進(jìn)入后你會(huì)發(fā)現(xiàn)有句話
大意是:Commons HttpClient這個(gè)項(xiàng)目已經(jīng)不再維護(hù)了症脂,它已經(jīng)被Apache HttpComponents替代了。也就是說(shuō)我們以后要用的話就用新的。點(diǎn)這個(gè)Apache HttpComponents的鏈接進(jìn)去能看到它最新的版本是4.5诱篷,而且有快速上手的例子和專業(yè)的說(shuō)明文檔壶唤。有興趣并且英文好的朋友可以好好研究下哦 ~~
額~~那個(gè)~~我的英文不好,就不按照官網(wǎng)的來(lái)了棕所,直接給出我自己在網(wǎng)上學(xué)的練習(xí)案例~~
二闸盔、HttpClient入門(mén)實(shí)例
新建一個(gè)普通的maven項(xiàng)目:名字隨便起,我的叫:httpclient_learn
修改pom文件琳省,引入依賴
<dependency>
? ? <groupId>org.apache.httpcomponents</groupId>
? ? <artifactId>httpclient</artifactId>
? ? <version>4.5.8</version>
</dependency>
新建java類
復(fù)制代碼
package httpclient_learn;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class HttpClientTest {
? ?
? ? public static void main(String[] args) {
? ? ? ? //1.生成httpclient迎吵,相當(dāng)于該打開(kāi)一個(gè)瀏覽器
? ? ? ? CloseableHttpClient httpClient = HttpClients.createDefault();
? ? ? ? CloseableHttpResponse response = null;
? ? ? ? //2.創(chuàng)建get請(qǐng)求,相當(dāng)于在瀏覽器地址欄輸入 網(wǎng)址
? ? ? ? HttpGet request = new HttpGet("https://www.cnblogs.com/");
? ? ? ? try {
? ? ? ? ? ? //3.執(zhí)行g(shù)et請(qǐng)求针贬,相當(dāng)于在輸入地址欄后敲回車鍵
? ? ? ? ? ? response = httpClient.execute(request);
? ? ? ? ? ?
? ? ? ? ? ? //4.判斷響應(yīng)狀態(tài)為200击费,進(jìn)行處理
? ? ? ? ? ? if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
? ? ? ? ? ? ? ? //5.獲取響應(yīng)內(nèi)容
? ? ? ? ? ? ? ? HttpEntity httpEntity = response.getEntity();
? ? ? ? ? ? ? ? String html = EntityUtils.toString(httpEntity, "utf-8");
? ? ? ? ? ? ? ? System.out.println(html);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? //如果返回狀態(tài)不是200,比如404(頁(yè)面不存在)等桦他,根據(jù)情況做處理蔫巩,這里略
? ? ? ? ? ? ? ? System.out.println("返回狀態(tài)不是200");
? ? ? ? ? ? ? ? System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
? ? ? ? ? ? }
? ? ? ? } catch (ClientProtocolException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } finally {
? ? ? ? ? ? //6.關(guān)閉
? ? ? ? ? ? HttpClientUtils.closeQuietly(response);
? ? ? ? ? ? HttpClientUtils.closeQuietly(httpClient);
? ? ? ? }
? ? }
}
復(fù)制代碼
執(zhí)行代碼,我們會(huì)發(fā)現(xiàn)打印出來(lái)的其實(shí)就是首頁(yè)完整的html代碼
復(fù)制代碼
<!DOCTYPE html>
<html lang="zh-cn">
<head>
? ? //Java開(kāi)發(fā)老菜鳥(niǎo)備注:由于內(nèi)容太多快压,具體不再貼出來(lái)了
</head>
<body>
//Java開(kāi)發(fā)老菜鳥(niǎo)備注:由于內(nèi)容太多圆仔,具體內(nèi)容不再貼出來(lái)了
</body> </html>
復(fù)制代碼
操作成功!
好了蔫劣,到這里就完成了一個(gè)簡(jiǎn)單的小例子坪郭。
爬一個(gè)網(wǎng)站不過(guò)癮,再來(lái)一打拦宣。接下來(lái)我們換個(gè)網(wǎng)站:https://www.tuicool.com/截粗,你會(huì)發(fā)現(xiàn)結(jié)果是這樣的:
復(fù)制代碼
返回狀態(tài)不是200
<!DOCTYPE html>
<html>
? ? <head>
? ? ? ? ? <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
? ? </head>
? ? <body>
? ? ? ? <p>系統(tǒng)檢測(cè)親不是真人行為,因系統(tǒng)資源限制鸵隧,我們只能拒絕你的請(qǐng)求绸罗。如果你有疑問(wèn),可以通過(guò)微博 http://weibo.com/tuicool2012/ 聯(lián)系我們豆瘫。</p>
? ? </body>
</html>
復(fù)制代碼
爬蟲(chóng)程序被識(shí)別了珊蟀,怎么辦呢? 別著急外驱,慢慢往下看
三育灸、復(fù)雜應(yīng)用
第二個(gè)網(wǎng)站訪問(wèn)不了,是因?yàn)榫W(wǎng)站有反爬蟲(chóng)的處理昵宇,怎么繞過(guò)他呢?
1.最簡(jiǎn)單的是對(duì)請(qǐng)求頭進(jìn)行偽裝磅崭,看代碼,加上紅框里面的內(nèi)容后再執(zhí)行
你會(huì)發(fā)現(xiàn)返回結(jié)果變了瓦哎,有真內(nèi)容了(紅字警告先不管它砸喻,我們起碼獲取到了html內(nèi)容)
那代碼中新加的那段內(nèi)容是哪里來(lái)的呢柔逼?
請(qǐng)打開(kāi)谷歌瀏覽器的F12,對(duì)就是這里了:
當(dāng)然我們還可以設(shè)置請(qǐng)求的其他頭信息割岛,如cookie等
2.上面說(shuō)的是偽裝成瀏覽器愉适,其實(shí)如果你偽裝了之后,如果短時(shí)間內(nèi)一直多次訪問(wèn)的話癣漆,網(wǎng)站會(huì)對(duì)你的ip進(jìn)行封殺维咸,這個(gè)時(shí)候就需要換個(gè)ip地址了,使用代理IP
網(wǎng)上有一些免費(fèi)的代理ip網(wǎng)站惠爽,比如xici
我們選擇那些存活時(shí)間久并且剛剛被驗(yàn)證的ip癌蓖,我這里選擇了“112.85.168.223:9999”,代碼如下
復(fù)制代碼
//2.創(chuàng)建get請(qǐng)求疆股,相當(dāng)于在瀏覽器地址欄輸入 網(wǎng)址
? ? ? ? HttpGet request = new HttpGet("https://www.tuicool.com/");
? ? ? ? //設(shè)置請(qǐng)求頭费坊,將爬蟲(chóng)偽裝成瀏覽器
? ? ? ? request.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
? ? ? ? HttpHost proxy = new HttpHost("112.85.168.223", 9999);
? ? ? ? RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
? ? ? ? request.setConfig(config);
復(fù)制代碼
執(zhí)行代碼,能正常返回html結(jié)果旬痹。如果代理ip剛好不能用的話附井,會(huì)報(bào)錯(cuò),如下顯示連接超時(shí)两残,這個(gè)時(shí)候需要更換一個(gè)新的代理ip
3.另外永毅,程序被識(shí)別出來(lái)很大原因是短時(shí)間內(nèi)做了太多訪問(wèn),這個(gè)是正常人不會(huì)有的頻率人弓,因此我們也可以放慢爬取的速度沼死,讓程序sleep一段時(shí)間再爬下一個(gè)也是一種反 反爬蟲(chóng)的簡(jiǎn)單方法。
四崔赌、結(jié)束語(yǔ)
這篇簡(jiǎn)單介紹了下httpclient和它的官網(wǎng)意蛀,并用代碼說(shuō)明了如何使用它,也提到了如果遇到反爬蟲(chóng)的話我們還可以用一些簡(jiǎn)單的反反爬蟲(chóng)方法進(jìn)行應(yīng)對(duì)健芭。