Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产成人精品综合在线,久久精品一区二区国产,欧美韩国精品另类综合

          整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢(xún)熱線:

          好程序員Java教程分享使用HttpClient抓取頁(yè)面內(nèi)容

          程序員Java教程分享使用HttpClient抓取頁(yè)面內(nèi)容

          使用HttpClient工具來(lái)發(fā)送Http請(qǐng)求

          1.簡(jiǎn)介

          HttpClient 是 Apache Jakarta Common 下的子項(xiàng)目,用來(lái)提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶(hù)端編程工具包,并且它支持 HTTP 協(xié)議最新的版本和建議。HttpClient 已經(jīng)應(yīng)用在很多的項(xiàng)目中,比如 Apache Jakarta 上很著名的另外兩個(gè)開(kāi)源項(xiàng)目 Cactus 和 HTMLUnit 都使用了 HttpClient。

          HttpClient 相比傳統(tǒng) JDK 自帶的 URLConnection,增加了易用性和靈活性,它不僅是客戶(hù)端發(fā)送 HTTP 請(qǐng)求變得容易,而且也方便了開(kāi)發(fā)人員測(cè)試接口(基于 HTTP 協(xié)議的),即提高了開(kāi)發(fā)的效率,也方便提高代碼的健壯性。因此熟練掌握 HttpClient 是很重要的必修內(nèi)容,掌握 HttpClient 后,相信對(duì)于 HTTP 協(xié)議的了解會(huì)更加深入。

          2.應(yīng)用場(chǎng)景

          圖片1

          3.HttpClient工具的使用

          1)添加依賴(lài)

          <!-- Apache Http Begin -->
          <dependency>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpclient</artifactId>
          <version>4.5.5</version>
          </dependency>
          <dependency>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>fluent-hc</artifactId>
          <version>4.5.5</version>
          </dependency>
          <dependency>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpmime</artifactId>
          <version>4.5.5</version>
          </dependency>
          <!-- Apache Http End -->

          2)編寫(xiě)測(cè)試代碼

          @Test
          public void testHttpClient() throws IOException {
          //1.獲得HttpClient對(duì)象
          CloseableHttpClient client = HttpClients.createDefault();
          //2.創(chuàng)建請(qǐng)求對(duì)象,如果是post請(qǐng)求 HttpPost 如果是get請(qǐng)求 HttpGet對(duì)象
          String uri = "http://www.baidu.com";
          HttpGet get = new HttpGet(uri);
          //3.執(zhí)行g(shù)et請(qǐng)求,獲得響應(yīng)消息對(duì)象
          CloseableHttpResponse response = client.execute(get);
          //4.獲取響應(yīng)行
          StatusLine statusLine = response.getStatusLine();
          //5.獲取狀態(tài)碼
          int code = statusLine.getStatusCode();
          if(code==200){
          //響應(yīng)成功
          HttpEntity entity = response.getEntity();
          //6.獲取響應(yīng)體中的內(nèi)容
          // InputStream is = entity.getContent();
          // byte[] b = new byte[8192];
          // int len = 0;
          // while((len = is.read(b))!=-1){
          // System.out.println(new String(b,0,len));
          // }
          // is.close();
          System.out.println(EntityUtils.toString(entity, "utf-8"));
          }

          . HTTP請(qǐng)求格式

          做過(guò)Socket編程的人都知道,當(dāng)我們?cè)O(shè)計(jì)一個(gè)通信協(xié)議時(shí),“消息頭/消息體”的分割方式是很常用的,消息頭告訴對(duì)方這個(gè)消息是干什么的,消息體告訴對(duì) 方怎么干。HTTP協(xié)議傳輸?shù)南⒁彩沁@樣規(guī)定的,每一個(gè)HTTP包都分為HTTP頭和HTTP體兩部分,消息體是可選的,而消息頭是必須的。每當(dāng)我們打 開(kāi)一個(gè)網(wǎng)頁(yè),在上面點(diǎn)擊右鍵,選擇“查看源文件”,這時(shí)看到的HTML代碼就是HTTP的消息體,那么消息頭可以通過(guò)瀏覽器的開(kāi)發(fā)工具或者插件可以看到, 如果火狐的Firebug,IE的Httpwatch。

          客戶(hù)端通過(guò)發(fā)送 HTTP 請(qǐng)求向服務(wù)器請(qǐng)求對(duì)資源的訪問(wèn)。 它向服務(wù)器傳遞了一個(gè)數(shù)據(jù)塊,也就是請(qǐng)求信息,HTTP 請(qǐng)求由三部分組成:請(qǐng)求行、 請(qǐng)求頭和請(qǐng)求正文。

          請(qǐng)求行:請(qǐng)求方法 URI 協(xié)議/版本

          請(qǐng)求頭(Request Header)

          請(qǐng)求正文

          下面是一個(gè)HTTP請(qǐng)求的數(shù)據(jù):

          POST /index.php HTTP/1.1

          Host: localhost

          User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2

          Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

          Accept-Language: zh-cn,zh;q=0.5

          Accept-Encoding: gzip, deflate

          Connection: keep-alive

          Referer: http://localhost/

          Content-Length:25

          Content-Type:application/x-www-form-urlencoded

          username=aa&password=1234

          1、請(qǐng)求行:請(qǐng)求方法URI協(xié)議/版本

          請(qǐng)求的第一行是“方法 URL 協(xié)議/版本”,并以 回車(chē)換行作為結(jié)尾。請(qǐng)求行以空格分隔。格式如下:

          POST /index.php HTTP/1.1

          以上代碼中“GET”代表請(qǐng)求方法,“//ndex.php”表示URI,“HTTP/1.1代表協(xié)議和協(xié)議的版本。

          根據(jù)HTTP標(biāo)準(zhǔn),HTTP請(qǐng)求可以使用多種請(qǐng)求方法。例如:HTTP1.1支持7種請(qǐng)求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet應(yīng)用中,最常用的方法是GET和POST。

          URL完整地指定了要訪問(wèn)的網(wǎng)絡(luò)資源,通常只要給出相對(duì)于服務(wù)器的根目錄的相對(duì)目錄即可,因此總是以“/”開(kāi)頭,最后,協(xié)議版本聲明了通信過(guò)程中使用HTTP的版本。

          請(qǐng)求方法

          在 HTTP 協(xié)議中,HTTP 請(qǐng)求可以使用多種請(qǐng)求方法,這些方法指明了要以何種方式來(lái)訪問(wèn) Request-URI 所標(biāo)識(shí)的資源。HTTP1.1 支持的請(qǐng)求方法如下表所示:

          HTTP1.1 中的請(qǐng)求方式:

          方法

          作用

          GET

          請(qǐng)求獲取由 Request-URI 所標(biāo)識(shí)的資源

          POST

          請(qǐng)求服務(wù)器接收在請(qǐng)求中封裝的實(shí)體,并將其作為由 Request-Line 中的 Request-URI 所標(biāo)識(shí)的資源的一部分

          HEAD

          請(qǐng)求獲取由 Request-URI 所標(biāo)識(shí)的資源的響應(yīng)消息報(bào)頭

          PUT

          請(qǐng)求服務(wù)器存儲(chǔ)一個(gè)資源,并用 Request-URI 作為其標(biāo)識(shí)符

          DELETE

          請(qǐng)求服務(wù)器刪除由 Request-URI 所標(biāo)識(shí)的資源

          TRACE

          請(qǐng)求服務(wù)器回送到的請(qǐng)求信息,主要用于測(cè)試或診斷

          CONNECT

          保留將來(lái)使用

          OPTIONS

          請(qǐng)求查詢(xún)服務(wù)器的性能,或者查詢(xún)與資源相關(guān)的選項(xiàng)和需求

          重點(diǎn)介紹 GET、POST 和 HEAD 三個(gè)方法:

          (1)GET

          GET 方法用于獲取由 Request-URI 所標(biāo)識(shí)的資源的信息,常見(jiàn)的形式是:

          GET Request-URI HTTP/1.1

          GET方法是默認(rèn)的HTTP請(qǐng)求方法,例如當(dāng)我們通過(guò)在瀏覽器的地址欄中直接輸入網(wǎng)址的方式去訪問(wèn)網(wǎng)頁(yè)的時(shí)候,瀏覽器采用的就是 GET 方法向服務(wù)器獲取資源。

          我們可以使用GET方法來(lái)提交表單數(shù)據(jù),用GET方法提交的表單數(shù)據(jù)只經(jīng)過(guò)了簡(jiǎn)單的編碼,同時(shí)它將作為URL的一部分向服務(wù)器發(fā)送,因此,如果使用GET方法來(lái)提交表單數(shù)據(jù)就存在著安全隱患上。例如:

          Http://localhost/login.php?username=aa&password=1234

          從上面的URL請(qǐng)求中,很容易就可以辯認(rèn)出表單提交的內(nèi)容。(?之后的內(nèi)容)另外由于GET方法提交的數(shù)據(jù)是作為URL請(qǐng)求的一部分所以提交的數(shù)據(jù)量不能太大。這是因?yàn)闉g覽器對(duì)url的長(zhǎng)度有限制

          各種瀏覽器也會(huì)對(duì)url的長(zhǎng)度有所限制,下面是幾種常見(jiàn)瀏覽器的url長(zhǎng)度限制:(單位:字符)

          IE : 2803

          Firefox:65536

          Chrome:8182

          Safari:80000

          Opera:190000

          (2)POST

          POST方法是GET方法的一個(gè)替代方法,它主要是向Web服務(wù)器提交表單數(shù)據(jù),尤其是大批量的數(shù)據(jù)。 在請(qǐng)求頭信息結(jié)束之后的兩個(gè)回車(chē)換行之后(實(shí)際是空一行),就是表單提交的數(shù)據(jù)。如上面提到的post表單數(shù)據(jù):

          username=aa&password=1234

          POST方法克服了GET方法的一些缺點(diǎn)。通過(guò)POST方法提交表單數(shù)據(jù)時(shí),數(shù)據(jù)不是作為URL請(qǐng)求的一部分而是作為標(biāo)準(zhǔn)數(shù)據(jù)傳送給Web服務(wù)器,這就克 服了GET方法中的信息無(wú)法保密和數(shù)據(jù)量太小的缺點(diǎn)。因此,出于安全的考慮以及對(duì)用戶(hù)隱私的尊重,通常表單提交時(shí)采用POST方法。

            從編程的角度來(lái)講,如果用戶(hù)通過(guò)GET方法提交數(shù)據(jù),則數(shù)據(jù)存放在QUERY_STRING環(huán)境變量中,而POST方法提交的數(shù)據(jù)則可以從標(biāo)準(zhǔn)輸入流中獲取。

          GET與POST方法有以下區(qū)別:

          1、 在客戶(hù)端,Get方式在通過(guò)URL提交數(shù)據(jù),數(shù)據(jù)在URL中可以看到;POST方式,數(shù)據(jù)放在HTTP包的body中。

          2、 GET方式提交的數(shù)據(jù)大小有限制(因?yàn)闉g覽器對(duì)URL的長(zhǎng)度有限制),而POST則沒(méi)有此限制。

          3、安全性問(wèn)題。正如在(1)中提到,使用 Get 的時(shí)候,參數(shù)會(huì)顯示在地址欄上,而 Post 不會(huì)。所以,如果這些數(shù)據(jù)是中文數(shù)據(jù)而且是非敏感數(shù)據(jù),那么使用 get;如果用戶(hù)輸入的數(shù)據(jù)不是中文字符而且包含敏感數(shù)據(jù),那么還是使用 post為好。

          4.、服務(wù)器取值方式不一樣。GET方式取值,如php可以使用$_GET來(lái)取得變量的值,而POST方式通過(guò)$_POST來(lái)獲取變量的值。

          (3)HEAD

          HEAD 方法與 GET 方法幾乎是相同的,它們的區(qū)別在于 HEAD 方法只是請(qǐng)求消息報(bào)頭,而不是完整的內(nèi)容。對(duì)于 HEAD 請(qǐng)求的回應(yīng)部分來(lái)說(shuō),它的 HTTP 頭部中包含的信息與通過(guò) GET 請(qǐng)求所得到的信息是相同的。利用這個(gè)方法,不必傳輸整個(gè)資源內(nèi)容,就可以得到 Request-URI 所標(biāo)識(shí)的資源的信息。這個(gè)方法通常被用于測(cè)試超鏈接的有效性,是否可以訪問(wèn),以及最近是否更新。

          要注意的是,在 HTML 文檔中,書(shū)寫(xiě) get 和 post,大小寫(xiě)都可以,但在 HTTP 協(xié)議中的 GET 和 POST 只能是大寫(xiě)形式。

          2. 請(qǐng)求頭

          每個(gè)頭域由一個(gè)域名,冒號(hào)(:)和域值三部分組成。域名是大小寫(xiě)無(wú)關(guān)的,域值前可以添加任何數(shù)量的空格符,頭域可以被擴(kuò)展為多行,在每行開(kāi)始處,使用至少一個(gè)空格或制表符。

          HTTP最常見(jiàn)的請(qǐng)求頭如下:

          Transport 頭域

          Connection:

          作用:表示是否需要持久連接。

          如果服務(wù)器看到這里的值為“Keep-Alive”,或者看到請(qǐng)求使用的是HTTP 1.1(HTTP 1.1默認(rèn)進(jìn)行持久連接),它就可以利用持久連接的優(yōu)點(diǎn),當(dāng)頁(yè)面包含多個(gè)元素時(shí)(例如Applet,圖片),顯著地減少下載所需要的時(shí)間。要實(shí)現(xiàn)這一點(diǎn),服務(wù)器需要在應(yīng)答中發(fā)送一個(gè)Content-Length頭,最簡(jiǎn)單的實(shí)現(xiàn)方法是:先把內(nèi)容寫(xiě)入 ByteArrayOutputStream,然后在正式寫(xiě)出內(nèi)容之前計(jì)算它的大小;

          例如: Connection: keep-alive 當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,如果客戶(hù)端再次訪問(wèn)這個(gè)服務(wù)器上的 網(wǎng)頁(yè),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接

          例如: Connection: close 代表一個(gè)Request完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接會(huì)關(guān)閉, 當(dāng)客戶(hù)端再次發(fā)送Request,需要重新建立TCP連接。

          Host(發(fā)送請(qǐng)求時(shí),該報(bào)頭域是必需的)

          Host請(qǐng)求報(bào)頭域主要用于指定被請(qǐng)求資源的Internet主機(jī)和端口號(hào),它通常從HTTP URL中提取出來(lái)的。

          eg:http://;localhost/index.html

          瀏覽器發(fā)送的請(qǐng)求消息中,就會(huì)包含Host請(qǐng)求報(bào)頭域,如下:

          Host:localhost

          此處使用缺省端口號(hào)80,若指定了端口號(hào)8080,則變成:Host:localhost:8080

          Client 頭域

          Accept:

          作用:瀏覽器可以接受的媒體類(lèi)型(MIME類(lèi)型),

          例如: Accept: text/html 代表瀏覽器可以接受服務(wù)器回發(fā)的類(lèi)型為 text/html 也就是我們常說(shuō)的html文檔, 如果服務(wù)器無(wú)法返回text/html類(lèi)型的數(shù)據(jù),服務(wù)器應(yīng)該返回一個(gè)406錯(cuò)誤(non acceptable)。

          通配符 * 代表任意類(lèi)型。例如 Accept: */* 代表瀏覽器可以處理所有類(lèi)型,(一般瀏覽器發(fā)給服務(wù)器都是發(fā)這個(gè))

          Accept-Encoding:

          作用: 瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法(gzip,deflate),(注意:這不是只字符編碼);

          例如: Accept-Encoding: gzip, deflate。Server能夠向支持gzip/deflate的瀏覽器返回經(jīng)gzip或者deflate編碼的HTML頁(yè)面。 許多情形下這可以減少5到10倍的下載時(shí)間,也節(jié)省帶寬。

          Accept-Language:

          作用: 瀏覽器申明自己接收的語(yǔ)言。

          語(yǔ)言跟字符集的區(qū)別:中文是語(yǔ)言,中文有多種字符集,比如big5,gb2312,gbk等等;

          例如: Accept-Language:zh-cn 。如果請(qǐng)求消息中沒(méi)有設(shè)置這個(gè)報(bào)頭域,服務(wù)器假定客戶(hù)端對(duì)各種語(yǔ)言都可以接受。

          User-Agent:

          作用:告訴HTTP服務(wù)器, 客戶(hù)端使用的操作系統(tǒng)和瀏覽器的名稱(chēng)和版本.

          我們上網(wǎng)登陸論壇的時(shí)候,往往會(huì)看到一些歡迎信息,其中列出了你的操作系統(tǒng)的名稱(chēng)和版本,你所使用的瀏覽器的名稱(chēng)和版本,這往往讓很多人感到很神 奇,實(shí)際上, 服務(wù)器應(yīng)用程序就是從User-Agent這個(gè)請(qǐng)求報(bào)頭域中獲取到這些信息User-Agent請(qǐng)求報(bào)頭域允許客戶(hù)端將它的操作系統(tǒng)、瀏覽 器和其它屬性告訴服務(wù)器。

          例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)

          Accept-Charset:

          作用:瀏覽器申明自己接收的字符集,這就是本文前面介紹的各種字符集和字符編碼,如gb2312,utf-8(通常我們說(shuō)Charset包括了相應(yīng)的字符編碼方案);

          例如:Accept-Charset:iso-8859-1,gb2312.如果在請(qǐng)求消息中沒(méi)有設(shè)置這個(gè)域,缺省是任何字符集都可以接受。

          Authorization:授權(quán)信息,通常出現(xiàn)在對(duì)服務(wù)器發(fā)送的WWW-Authenticate頭的應(yīng)答中;

          Authorization請(qǐng)求報(bào)頭域主要用于證明客戶(hù)端有權(quán)查看某個(gè)資源。當(dāng)瀏覽器訪問(wèn)一個(gè)頁(yè)面時(shí),如果收到服務(wù)器的響應(yīng)代碼為401(未授權(quán)),可以發(fā)送一個(gè)包含Authorization請(qǐng)求報(bào)頭域的請(qǐng)求,要求服務(wù)器對(duì)其進(jìn)行驗(yàn)證。

          Cookie/Login 頭域

          Cookie:

          作用: 最重要的header, 將cookie的值發(fā)送給HTTP 服務(wù)器

          Entity頭域

          Content-Length

          作用:發(fā)送給HTTP服務(wù)器數(shù)據(jù)的長(zhǎng)度。即請(qǐng)求消息正文的長(zhǎng)度;

          例如: Content-Length: 38

          Content-Type:

          作用:

          例如:Content-Type: application/x-www-form-urlencoded

          Miscellaneous 頭域

          Referer:

          作用: 提供了Request的上下文信息的服務(wù)器,告訴服務(wù)器我是從哪個(gè)鏈接過(guò)來(lái)的,比如從我主頁(yè)上鏈接到一個(gè)朋友那里, 他的服務(wù)器就能夠從HTTP Referer中統(tǒng)計(jì)出每天有多少用戶(hù)點(diǎn)擊我主頁(yè)上的鏈接訪問(wèn) 他的網(wǎng)站。

          例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT

          Cache 頭域

          If-Modified-Since:

          作用: 把瀏覽器端緩存頁(yè)面的最后修改時(shí)間發(fā)送到服務(wù)器去,服務(wù)器會(huì)把這個(gè)時(shí)間與服務(wù)器上實(shí)際文件的最后修改時(shí)間進(jìn)行對(duì)比。如果時(shí)間一致,那么返回304,客戶(hù)端 就直接使用本地緩存文件。如果時(shí)間不一致,就會(huì)返回200和新的文件內(nèi)容??蛻?hù)端接到之后,會(huì)丟棄舊文件,把新文件緩存起來(lái),并顯示在瀏覽器中。

          例如:If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT。

          If-None-Match:

          作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 當(dāng)用戶(hù)再次請(qǐng)求該資源時(shí),將在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服務(wù)器驗(yàn)證資源的ETag沒(méi)有改變(該資源沒(méi)有更新),將返回一個(gè)304狀態(tài)告訴客戶(hù)端使用 本地緩存文件。否則將返回200狀態(tài)和新的資源和Etag. 使用這樣的機(jī)制將提高網(wǎng)站的性能

          例如: If-None-Match: "03f2b33c0bfcc1:0"

          Pragma:

          作用: 防止頁(yè)面被緩存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一樣

          Pargma只有一個(gè)用法, 例如: Pragma: no-cache

          注意: 在HTTP/1.0版本中,只實(shí)現(xiàn)了Pragema:no-cache, 沒(méi)有實(shí)現(xiàn)Cache-Control

          Cache-Control:

          作用: 這個(gè)是非常重要的規(guī)則。 這個(gè)用來(lái)指定Response-Request遵循的緩存機(jī)制。各個(gè)指令含義如下

          Cache-Control:Public 可以被任何緩存所緩存()

          Cache-Control:Private 內(nèi)容只緩存到私有緩存中

          Cache-Control:no-cache 所有內(nèi)容都不會(huì)被緩存

          2. HTTP響應(yīng)格式

          在接收和解釋請(qǐng)求消息后,服務(wù)器會(huì)返回一個(gè) HTTP 響應(yīng)消息。與 HTTP 請(qǐng)求類(lèi)似,HTTP 響應(yīng)也是由三個(gè)部分組成,分別是:狀態(tài)行、消息報(bào)頭和響應(yīng)正文。如:

          HTTP/1.1 200 OK

          Date: Sun, 17 Mar 2013 08:12:54 GMT

          Server: Apache/2.2.8 (Win32) PHP/5.2.5

          X-Powered-By: PHP/5.2.5

          Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/

          Expires: Thu, 19 Nov 1981 08:52:00 GMT

          Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

          Pragma: no-cache

          Content-Length: 4393

          Keep-Alive: timeout=5, max=100

          Connection: Keep-Alive

          Content-Type: text/html; charset=utf-8

          <html>

          <head>

          <title>HTTP響應(yīng)示例<title>

          </head>

          <body>

          Hello HTTP!

          </body>

          </html>

          1、狀態(tài)行

          狀態(tài)行由協(xié)議版本、數(shù)字形式的狀態(tài)代碼,及相應(yīng)的狀態(tài)描述組成,各元素之間以空格分隔,結(jié)尾時(shí)回車(chē)換行符,格式如下:

          HTTP-Version Status-Code Reason-Phrase CRLF

          HTTP-Version 表示服務(wù)器 HTTP 協(xié)議的版本,Status-Code 表示服務(wù)器發(fā)回的響應(yīng)代碼,Reason-Phrase 表示狀態(tài)代碼的文本描述,CRLF 表示回車(chē)換行。例如:

          HTTP/1.1 200 OK (CRLF)

          狀態(tài)代碼與狀態(tài)描述

          狀態(tài)代碼由 3 位數(shù)字組成, 表示請(qǐng)求是否被理解或被滿(mǎn)足,狀態(tài)描述給出了關(guān)于狀態(tài)碼的簡(jiǎn)短的文字描述。狀態(tài)碼的第一個(gè)數(shù)字定義了響應(yīng)類(lèi)別,后面兩位數(shù)字沒(méi)有具體分類(lèi)。第一個(gè)數(shù)字有 5 種取值,如下所示。

          • 1xx:指示信息——表示請(qǐng)求已經(jīng)接受,繼續(xù)處理
          • 2xx:成功——表示請(qǐng)求已經(jīng)被成功接收、理解、接受。
          • 3xx:重定向——要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作
          • 4xx:客戶(hù)端錯(cuò)誤——請(qǐng)求有語(yǔ)法錯(cuò)誤或請(qǐng)求無(wú)法實(shí)現(xiàn)
          • 5xx:服務(wù)器端錯(cuò)誤——服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求。

          常見(jiàn)狀態(tài)代碼、狀態(tài)描述、說(shuō)明:

          200 OK //客戶(hù)端請(qǐng)求成功

          400 Bad Request //客戶(hù)端請(qǐng)求有語(yǔ)法錯(cuò)誤,不能被服務(wù)器所理解

          401 Unauthorized //請(qǐng)求未經(jīng)授權(quán),這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用

          403 Forbidden //服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù)

          404 Not Found //請(qǐng)求資源不存在,eg:輸入了錯(cuò)誤的URL

          500 Internal Server Error //服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤

          503 Server Unavailable //服務(wù)器當(dāng)前不能處理客戶(hù)端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常

          2、響應(yīng)正文

          響應(yīng)正文就是服務(wù)器返回的資源的內(nèi)容,響應(yīng)頭和正文之間也必須用空行分隔。如:

          1. <html>
          2. <head>
          3. <title>HTTP響應(yīng)示例<title>
          4. </head>
          5. <body>
          6. Hello HTTP!
          7. </body>
          8. </html>

          3 、響應(yīng)頭信息

          HTTP最常見(jiàn)的響應(yīng)頭如下所示:

          Cache頭域

          Date:

          作用:生成消息的具體時(shí)間和日期,即當(dāng)前的GMT時(shí)間。

          例如: Date: Sun, 17 Mar 2013 08:12:54 GMT

          Expires:

          作用: 瀏覽器會(huì)在指定過(guò)期時(shí)間內(nèi)使用本地緩存,指明應(yīng)該在什么時(shí)候認(rèn)為文檔已經(jīng)過(guò)期,從而不再緩存它。

          例如: Expires: Thu, 19 Nov 1981 08:52:00 GMT  

          Vary

          作用:

          例如: Vary: Accept-Encoding

          Cookie/Login 頭域

          P3P

          作用: 用于跨域設(shè)置Cookie, 這樣可以解決iframe跨域訪問(wèn)cookie的問(wèn)題

          例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR

          Set-Cookie

          作用: 非常重要的header, 用于把cookie 發(fā)送到客戶(hù)端瀏覽器, 每一個(gè)寫(xiě)入cookie都會(huì)生成一個(gè)Set-Cookie.

          例如: Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/

          Entity實(shí)體頭域:

          實(shí)體內(nèi)容的屬性,包括實(shí)體信息類(lèi)型,長(zhǎng)度,壓縮方法,最后一次修改時(shí)間,數(shù)據(jù)有效性等。

          ETag:

          作用: 和If-None-Match 配合使用。 (實(shí)例請(qǐng)看上節(jié)中If-None-Match的實(shí)例)

          例如: ETag: "03f2b33c0bfcc1:0"

          Last-Modified:

          作用: 用于指示資源的最后修改日期和時(shí)間。(實(shí)例請(qǐng)看上節(jié)的If-Modified-Since的實(shí)例)

          例如: Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT

          Content-Type:

          作用:WEB服務(wù)器告訴瀏覽器自己響應(yīng)的對(duì)象的類(lèi)型和字符集,

          例如:

          Content-Type: text/html; charset=utf-8

            Content-Type:text/html;charset=GB2312

            Content-Type: image/jpeg

          Content-Length:

          指明實(shí)體正文的長(zhǎng)度,以字節(jié)方式存儲(chǔ)的十進(jìn)制數(shù)字來(lái)表示。在數(shù)據(jù)下行的過(guò)程中,Content-Length的方式要預(yù)先在服務(wù)器中緩存所有數(shù)據(jù),然后所有數(shù)據(jù)再一股腦兒地發(fā)給客戶(hù)端。

            例如: Content-Length: 19847

          Content-Encoding:

          作用:文檔的編碼(Encode)方法。一般是壓縮方式。

          WEB服務(wù)器表明自己使用了什么壓縮方法(gzip,deflate)壓縮響應(yīng)中的對(duì)象。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時(shí)間。

          例如:Content-Encoding:gzip

          Content-Language:

          作用: WEB服務(wù)器告訴瀏覽器自己響應(yīng)的對(duì)象的語(yǔ)言者

          例如: Content-Language:da

          Miscellaneous 頭域

          Server:

          作用:指明HTTP服務(wù)器的軟件信息

          例如:Apache/2.2.8 (Win32) PHP/5.2.5

          X-Powered-By:

          作用:表示網(wǎng)站是用什么技術(shù)開(kāi)發(fā)的

          例如: X-Powered-By: PHP/5.2.5

          Transport頭域

          Connection:

          例如: Connection: keep-alive 當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,如果客戶(hù)端再次訪問(wèn)這個(gè)服務(wù)器上的網(wǎng)頁(yè),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接

          例如: Connection: close 代表一個(gè)Request完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接會(huì)關(guān)閉, 當(dāng)客戶(hù)端再次發(fā)送Request,需要重新建立TCP連接。

          Location頭域

          Location:

          作用: 用于重定向一個(gè)新的位置, 包含新的URL地址

          實(shí)例請(qǐng)看304狀態(tài)實(shí)例

          HTTP協(xié)議是無(wú)狀態(tài)的和Connection: keep-alive的區(qū)別

            無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒(méi)有記憶能力,服務(wù)器不知道客戶(hù)端是什么狀態(tài)。從另一方面講,打開(kāi)一個(gè)服務(wù)器上的網(wǎng)頁(yè)和你之前打開(kāi)這個(gè)服務(wù)器上的網(wǎng)頁(yè)之間沒(méi)有任何聯(lián)系。

            HTTP是一個(gè)無(wú)狀態(tài)的面向連接的協(xié)議,無(wú)狀態(tài)不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協(xié)議(無(wú)連接)。

            從HTTP/1.1起,默認(rèn)都開(kāi)啟了Keep-Alive,保持連接特性,簡(jiǎn)單地說(shuō),當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,如果客戶(hù)端再次訪問(wèn)這個(gè)服務(wù)器上的網(wǎng)頁(yè),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接。

            Keep-Alive不會(huì)永久保持連接,它有一個(gè)保持時(shí)間,可以在不同的服務(wù)器軟件(如Apache)中設(shè)定這個(gè)時(shí)間。

          3. 瀏覽器緩存

          瀏覽器緩存:包括頁(yè)面html緩存和圖片js,css等資源的緩存。如下圖,瀏覽器緩存是基于把頁(yè)面信息保存到用戶(hù)本地電腦硬盤(pán)里。

          1、緩存的優(yōu)點(diǎn):

          1)服務(wù)器響應(yīng)更快:因?yàn)檎?qǐng)求從緩存服務(wù)器(離客戶(hù)端更近)而不是源服務(wù)器被相應(yīng),這個(gè)過(guò)程耗時(shí)更少,讓服務(wù)器看上去響應(yīng)更快。

          2)減少網(wǎng)絡(luò)帶寬消耗:當(dāng)副本被重用時(shí)會(huì)減低客戶(hù)端的帶寬消耗;客戶(hù)可以節(jié)省帶寬費(fèi)用,控制帶寬的需求的增長(zhǎng)并更易于管理。

          2、緩存工作原理

          頁(yè)面緩存狀態(tài)是由http header決定的,一個(gè)瀏覽器請(qǐng)求信息,一個(gè)是服務(wù)器響應(yīng)信息。主要包括Pragma: no-cache、Cache-Control、 Expires、 Last-Modified、If-Modified-Since。其中Pragma: no-cache由HTTP/1.0規(guī)定,Cache-Control由HTTP/1.1規(guī)定。

          工作原理圖:

          從圖中我們可以看到原理主要分三步:

          1. 第一次請(qǐng)求:瀏覽器通過(guò)http的header報(bào)頭,附帶Expires,Cache-Control,Last-Modified/Etag向服務(wù)器請(qǐng)求,此時(shí)服務(wù)器記錄第一次請(qǐng)求的Last-Modified/Etag
          2. 再次請(qǐng)求:當(dāng)瀏覽器再次請(qǐng)求的時(shí)候,請(qǐng)求頭附帶Expires,Cache-Control,If-Modified-Since/Etag向服務(wù)器請(qǐng)求
          3. 服務(wù)器根據(jù)第一次記錄的Last-Modified/Etag和再次請(qǐng)求的If-Modified-Since/Etag做對(duì)比,判斷是否需要更新,服務(wù)器通過(guò)這兩個(gè)頭判斷本地資源未發(fā)生變化,客 戶(hù)端不需要重新下載,返回304響應(yīng)。常見(jiàn)流程如下圖所示:

          與緩存相關(guān)的HTTP擴(kuò)展消息頭

          Expires:設(shè)置頁(yè)面過(guò)期時(shí)間,格林威治時(shí)間GMT

          Cache-Control:更細(xì)致的控制緩存的內(nèi)容

          Last-Modified:請(qǐng)求對(duì)象最后一次的修改時(shí)間 用來(lái)判斷緩存是否過(guò)期 通常由文件的時(shí)間信息產(chǎn)生

          ETag:響應(yīng)中資源的校驗(yàn)值,在服務(wù)器上某個(gè)時(shí)段是唯一標(biāo)識(shí)的。ETag是一個(gè)可以 與Web資源關(guān)聯(lián)的記號(hào)(token),和Last-Modified功能才不多,也是一個(gè)標(biāo)識(shí)符,一般和Last-Modified一起使用,加強(qiáng)服務(wù)器判斷的準(zhǔn)確度。

          Date:服務(wù)器的時(shí)間

          If-Modified-Since:客戶(hù)端存取的該資源最后一次修改的時(shí)間,用來(lái)和服務(wù)器端的Last-Modified做比較

          If-None-Match:客戶(hù)端存取的該資源的檢驗(yàn)值,同ETag。

          Cache-Control的主要參數(shù)

          Cache-Control: private/public Public 響應(yīng)會(huì)被緩存,并且在多用戶(hù)間共享。 Private 響應(yīng)只能夠作為私有的緩存,不能再用戶(hù)間共享。

          Cache-Control: no-cache:不進(jìn)行緩存

          Cache-Control: max-age=x:緩存時(shí)間 以秒為單位

          Cache-Control: must-revalidate:如果頁(yè)面是過(guò)期的 則去服務(wù)器進(jìn)行獲取。

          2、關(guān)于圖片,css,js,flash的緩存

          這個(gè)主要通過(guò)服務(wù)器的配置來(lái)實(shí)現(xiàn)這個(gè)技術(shù),如果使用apache服務(wù)器的話(huà),可以使用mod_expires模塊來(lái)實(shí)現(xiàn):

          編譯mod_expires模塊:

          Cd /root/httpd-2.2.3/modules/metadata

          /usr/local/apache/bin/apxs -i -a -c mod_expires.c //編譯

          編輯httpd.conf配置:添加下面內(nèi)容

          <IfModule mod_expires.c>

          ExpiresActive on

          ExpiresDefault "access plus 1 month"

          ExpiresByType text/html "access plus 1 months"

          ExpiresByType text/css "access plus 1 months"

          ExpiresByType image/gif "access plus 1 months"

          ExpiresByType image/jpeg "access plus 1 months"

          ExpiresByType image/jpg "access plus 1 months"

          ExpiresByType image/png "access plus 1 months"

          EXpiresByType application/x-shockwave-flash "access plus 1 months"

          EXpiresByType application/x-javascript "access plus 1 months"

          #ExpiresByType video/x-flv "access plus 1 months"

          </IfModule>

          解釋?zhuān)旱谝痪?-開(kāi)啟服務(wù)

          第二句--默認(rèn)時(shí)間是一個(gè)月

          在下面是關(guān)于各種類(lèi)型的資源的緩存時(shí)間設(shè)置

          .什么是jsoup

          jsoup 是一款 Java 的 HTML 解析器,可直接解析某個(gè) URL 地址、HTML 文本內(nèi)容。它提供了一套非常省力的 API,可通過(guò) DOM,CSS 以及類(lèi)似于 jQuery 的操作方法來(lái)取出和操作數(shù)據(jù),可操作 HTML 元素、屬性、文本。

          JSoup 功能

          jsoup 實(shí)現(xiàn) WHATWG HTML5 規(guī)范,并將 HTML 解析為與現(xiàn)代瀏覽器相同的 DOM。

          • 從 URL,文件或字符串中提取并解析 HTML。
          • 查找和提取數(shù)據(jù),使用 DOM 遍歷或 CSS 選擇器。
          • 操縱 HTML 元素,屬性和文本。
          • 根據(jù)安全的白名單清理用戶(hù)提交的內(nèi)容,以防止 XSS 攻擊。
          • 輸出整潔的 HTML。

          JSoup 主要類(lèi)

          大多數(shù)情況下,下面給出 3 個(gè)類(lèi)是我們需要重點(diǎn)了解的。

          Jsoup 類(lèi)

          Jsoup 類(lèi)是任何 Jsoup 程序的入口點(diǎn),并將提供從各種來(lái)源加載和解析 HTML 文檔的方法。 Jsoup 類(lèi)的一些重要方法如下:

          方法

          描述

          static Connection connect(String url)

          創(chuàng)建并返回 URL 的連接。

          static Document parse(File in, String charsetName)

          將指定的字符集文件解析成文檔。

          static Document parse(String html)

          將給定的 html 代碼解析成文檔。

          static String clean(String bodyHtml, Whitelist whitelist)

          從輸入 HTML 返回安全的 HTML,通過(guò)解析輸入 HTML 并通過(guò)允許的標(biāo)簽和屬性的白名單進(jìn)行過(guò)濾。

          Jsoup 類(lèi)的其他重要方法可以參見(jiàn) - https://jsoup.org/apidocs/org/jsoup/Jsoup.html

          Document 類(lèi)

          該類(lèi)表示通過(guò) Jsoup 庫(kù)加載 HTML 文檔??梢允褂么祟?lèi)執(zhí)行適用于整個(gè) HTML 文檔的操作。 Element 類(lèi)的重要方法可以參見(jiàn) - http://jsoup.org/apidocs/org/jsoup/nodes/Document.html

          Element 類(lèi)

          HTML 元素是由標(biāo)簽名稱(chēng),屬性和子節(jié)點(diǎn)組成。 使用 Element 類(lèi),您可以提取數(shù)據(jù),遍歷節(jié)點(diǎn)和操作 HTML。 Element 類(lèi)的重要方法可參見(jiàn) - http://jsoup.org/apidocs/org/jsoup/nodes/Element.html 。

          2.代碼工程

          實(shí)驗(yàn)?zāi)康?/h1>

          實(shí)現(xiàn)解析liuhaihua.cn首頁(yè)list

          pom.xml

          <?xml version="1.0" encoding="UTF-8"?>
          <project xmlns="http://maven.apache.org/POM/4.0.0"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
              <parent>
                  <artifactId>springboot-demo</artifactId>
                  <groupId>com.et</groupId>
                  <version>1.0-SNAPSHOT</version>
              </parent>
              <modelVersion>4.0.0</modelVersion>
          
              <artifactId>jsoup</artifactId>
          
              <properties>
                  <maven.compiler.source>8</maven.compiler.source>
                  <maven.compiler.target>8</maven.compiler.target>
              </properties>
              <dependencies>
          
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-web</artifactId>
                  </dependency>
          
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-autoconfigure</artifactId>
                  </dependency>
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-test</artifactId>
                      <scope>test</scope>
                  </dependency>
                  <dependency>
                      <groupId>org.jsoup</groupId>
                      <artifactId>jsoup</artifactId>
                      <version>1.12.1</version>
                  </dependency>
                  <dependency>
                      <groupId>org.apache.httpcomponents</groupId>
                      <artifactId>httpclient</artifactId>
                  </dependency>
          
              </dependencies>
          </project>

          controller

          package com.et.jsoup;
          
          import org.springframework.web.bind.annotation.RequestMapping;
          import org.springframework.web.bind.annotation.RestController;
          
          import java.util.HashMap;
          import java.util.Map;
          
          @RestController
          public class HelloWorldController {
              @RequestMapping("/hello")
              public Map<String, Object> showHelloWorld(){
                  Map<String, Object> map = new HashMap<>();
                  map =JsoupUtil.parseHtml("http://www.liuhaihua.cn/");
                  map.put("msg", "HelloWorld");
                  return map;
              }
          }

          工具類(lèi)

          package com.et.jsoup;
          import java.io.IOException;
          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
          
          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;
          import org.jsoup.Jsoup;
          import org.jsoup.nodes.Document;
          import org.jsoup.nodes.Element;
          import org.jsoup.select.Elements;
          
          /**
           * @author liuhaihua
           * @version 1.0
           * @ClassName JsoupUtil
           * @Description todo
           * @date 2024/06/24/ 9:16
           */
          
          public class JsoupUtil {
                  public static Map<String ,Object> parseHtml(String url){
                      Map<String,Object> map = new HashMap<>();
                      //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(url);
                      //設(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("60.13.42.232", 9999);
          //        RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
          //        request.setConfig(config);
                      try {
                          //3.執(zhí)行g(shù)et請(qǐng)求,相當(dāng)于在輸入地址欄后敲回車(chē)鍵
                          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);
          
                              /**
                               * 下面是Jsoup展現(xiàn)自我的平臺(tái)
                               */
                              //6.Jsoup解析html
                              Document document = Jsoup.parse(html);
                              //像js一樣,通過(guò)標(biāo)簽獲取title
                              System.out.println(document.getElementsByTag("title").first());
                              Elements blogmain = document.getElementsByClass("col-sm-8 blog-main");
          
          
                              //像js一樣,通過(guò)class 獲取列表下的所有博客
                              Elements postItems =  blogmain.first().getElementsByClass("fade-in");
                              //循環(huán)處理每篇博客
                              List<Map>  list =  new ArrayList<>();
                              for (Element postItem : postItems) {
                                  Map<String,Object> row = new HashMap<>();
                                  //像jquery選擇器一樣,獲取文章標(biāo)題元素
                                  Elements titleEle = postItem.select(".entry-title a");
                                  System.out.println("文章標(biāo)題:" + titleEle.text());;
                                  row.put("title",titleEle.text());
                                  System.out.println("文章地址:" + titleEle.attr("href"));
                                  row.put("href",titleEle.attr("href"));
                                  //像jquery選擇器一樣,獲取文章作者元素
                                  Elements footEle = postItem.select(".archive-content");
                                  System.out.println("文章概要:" + footEle.text());;
                                  row.put("summary",footEle.text());
                                  Elements view = postItem.select(".views");
                                  System.out.println( view.text());
                                  row.put("views",view.text());
                                  System.out.println("*********************************");
                                  list.add(row);
                              }
                              map.put("data",list);
          
                          } 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);
                      }
                      return  map;
                  }
                  public static void main(String[] args) {
                      parseHtml("http://www.liuhaihua.cn/");
                  }
          
          }

          DemoApplication.java

          package com.et.jsoup;
          
          import org.springframework.boot.SpringApplication;
          import org.springframework.boot.autoconfigure.SpringBootApplication;
          
          @SpringBootApplication
          public class DemoApplication {
          
             public static void main(String[] args) {
                SpringApplication.run(DemoApplication.class, args);
             }
          }

          以上只是一些關(guān)鍵代碼,所有代碼請(qǐng)參見(jiàn)下面代碼倉(cāng)庫(kù)

          代碼倉(cāng)庫(kù)

          • https://github.com/Harries/springboot-demo

          3.測(cè)試

          • 啟動(dòng)spring boot應(yīng)用
          • 訪問(wèn)http://127.0.0.1:8088/hello,返回解析結(jié)果

          4.引用

          • 官網(wǎng):https://jsoup.org/
          • GitHub:https://github.com/jhy/jsoup/
          • http://www.liuhaihua.cn/archives/710776.html

          主站蜘蛛池模板: 久久无码精品一区二区三区| 无码少妇一区二区三区芒果| 国产精品无码一区二区三区不卡 | 国产AV一区二区精品凹凸| 精品aⅴ一区二区三区| 国产一区二区三区播放心情潘金莲| 一区二区三区无码视频免费福利| 国产伦精品一区二区三区免.费 | 精品国产一区二区三区麻豆| 亚洲乱码日产一区三区 | 无码aⅴ精品一区二区三区浪潮| 无码精品前田一区二区| 国产成人av一区二区三区在线观看| 91午夜精品亚洲一区二区三区 | 人妻无码一区二区视频| 国产成人久久一区二区三区| 国产成人精品第一区二区| 日韩精品一区二区三区老鸭窝| 99精品国产高清一区二区| 日韩爆乳一区二区无码| 中文字幕一区二区三区在线观看| 日本中文字幕一区二区有码在线| 国精无码欧精品亚洲一区| 亚洲AV福利天堂一区二区三| 国产综合精品一区二区三区| 久久se精品动漫一区二区三区| 亚洲综合一区二区精品导航| 国产精品无码一区二区三区电影 | 日本精品少妇一区二区三区| 深夜福利一区二区| 日本亚洲国产一区二区三区| 国精无码欧精品亚洲一区| 日韩在线不卡免费视频一区| 99久久精品日本一区二区免费| 加勒比无码一区二区三区| 国产成人一区二区在线不卡| 中文字幕在线观看一区二区三区| 一区二区三区在线看| 污污内射在线观看一区二区少妇 | 区三区激情福利综合中文字幕在线一区亚洲视频1 | 国产精品日韩一区二区三区|