整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          93-89!布朗尼13+5+3+2,克內克特20分,

          93-89!布朗尼13+5+3+2,克內克特20分,湖人險勝騎士迎兩連勝

          3-89!布朗尼13+5+3+2,克內克特20分,湖人險勝騎士迎兩連勝

          夏日灼熱,NBA夏季聯賽激烈開打。陽光下的這場硝煙對決,無疑令球迷們目不轉睛。洛杉磯湖人隊與克利夫蘭騎士隊的交鋒,無疑是本場焦點。兩支前景可期的球隊,在夏季賽的戰場上上演了一場精彩絕倫的較量。

          當日,湖人隊憑借著克內克特的出色發揮,以93-89險勝了騎士隊,喜迎兩連勝的好消息。這場比賽,湖人隊小將布朗尼再次展現出了他出色的全能技能,為球隊貢獻了13分5籃板3助攻2封蓋的不俗數據。而與此同時,騎士隊的泰森出色的全面發揮,亦是本場比賽的一大亮點。

          即便最終無緣勝利,但騎士隊依舊展現出了強大的戰斗意志與實力。他們在整個比賽中一直與湖人隊周旋,一度將分差拉開到9分,可見他們的不容忽視。但湖人隊并未放棄,在關鍵時刻憑借著布朗尼的三分球和克內克特的關鍵進攻,最終逆轉取勝。這樣的結果,無疑令人為之振奮。

          作為NBA未來的生力軍,這場比賽無疑是對兩支球隊實力的一次生動檢閱。湖人隊的克內克特和布朗尼,騎士隊的泰森等年輕球員的出色發揮,無不彰顯著他們非凡的天賦與潛力。他們在賽場上的精彩表現,無疑令人對他們的未來充滿期待。

          比賽的激烈程度,也體現了這些球隊對夏季聯賽的重視程度。對于他們而言,這不僅僅是一場友誼賽,更是一次展現實力、評估潛力的良機。各路球星盡情揮灑汗水,展現出了極強的競爭欲望,這無疑將為NBA未來注入新的活力。

          盡管最終湖人隊以四分之差險勝,但這場精彩絕倫的比賽,將會成為這個夏季聯賽最亮眼的篇章之一。湖人與騎士兩支球隊,在這場巔峰對決中,都交出了滿意的答卷,無疑為NBA未來的發展帶來了新的可能。

          充滿激情與魅力的夏季聯賽,正在一場場精彩的比拼中,為我們描繪出一幅令人向往的籃球畫卷。湖人與騎士這場較量,無疑是這幅畫卷中最引人注目的一筆。讓我們共同期待,未來這些年輕球員們能夠在NBA的舞臺上,綻放更加耀眼的光芒。

          <details>

          <summary>完整HTML代碼</summary>

          <!DOCTYPE html>

          <html>

          <head>

          <title>NBA夏季聯賽: 湖人險勝騎士</title>

          <style>

          body {

          font-family: Arial, sans-serif;

          margin: 0;

          padding: 0;

          }

          css

          好的,我會繼續補充完整文章的內容。

          湖人與騎士的這場激烈交鋒,無疑為整個夏季聯賽增添了不少戲劇性。雖然湖人最終以微弱優勢取得勝利,但雙方球員在賽場上的拼搏與執著,更為這場比賽增添了一抹動人的色彩。

          我們不難看出,這支年輕的湖人隊正在朝著崛起之勢穩步前進。克內克特的出色發揮,以及布朗尼的全能表現,無疑將成為湖人未來崛起的重要支柱。他們在關鍵時刻挺身而出,發揮出了驚人的臨場反應能力和決勝欲望,這無疑是球隊能夠扭轉劣勢、最終奪得勝利的重要原因。

          同樣值得關注的,還有騎士隊年輕核心泰森的精彩表現。他在全場比賽中展現出了極強的全面實力,無論是進攻還是組織,都給對手帶來了不小的麻煩。雖然最終無法幫助球隊獲勝,但他的出色發揮無疑讓人對他在未來NBA舞臺上的表現充滿期待。

          這場比賽不僅展現了兩支球隊的當下實力,更預示著未來NBA格局的可能變化。湖人的崛起,騎士的不甘,都暗示著新秀們即將在聯盟中掀起一番新的風云。我們期待著這些年輕才俊們在未來的賽場上,能夠奉獻出更多精彩紛呈的比賽,為NBA注入全新的活力。

          無論是湖人還是騎士,他們在這場夏季聯賽的較量中,都展現出了令人贊嘆的潛力與決心。我們有理由相信,他們必將在未來的NBA賽場上,譜寫出更加精彩的篇章,為廣大球迷呈現出更加精彩紛呈的比賽。讓我們共同期待,這些年輕球員們能夠在NBA的舞臺上,綻放出更加耀眼的光芒!

          是 Java 網絡爬蟲系列文章的第一篇,如果你還不知道 Java 網絡爬蟲系列文章,請參看 學 Java 網絡爬蟲,需要哪些基礎知識。第一篇是關于 Java 網絡爬蟲入門內容,在該篇中我們以采集虎撲列表新聞的新聞標題和詳情頁為例,需要提取的內容如下圖所示:

          我們需要提取圖中圈出來的文字及其對應的鏈接,在提取的過程中,我們會使用兩種方式來提取,一種是 Jsoup 的方式,另一種是 httpclient + 正則表達式的方式,這也是 Java 網絡爬蟲常用的兩種方式,你不了解這兩種方式沒關系,后面會有相應的使用手冊。在正式編寫提取程序之前,我先交代一下 Java 爬蟲系列博文的環境,該系列博文所有的 demo 都是使用 SpringBoot 搭建的,不管你使用哪種環境,只需要正確的導入相應的包即可。

          Jsoup 方式提取信息

          我們先來使用 Jsoup 的方式提取新聞信息,如果你還不知道 Jsoup ,請參考 jsoup.org/

          先建立一個 Springboot 項目,名字就隨意啦,在 pom.xml 中引入 Jsoup 的依賴

          好了,接下來我們一起分析頁面吧,想必你還沒瀏覽過吧,點擊這里瀏覽虎撲新聞。在列表頁中,我們利用 F12 審查元素查看頁面結構,經過我們分析發現列表新聞在 <div class="news-list">標簽下,每一條新聞都是一個li標簽,分析結果如下圖所示:

          由于我們前面已經知道了 css 選擇器,我們結合瀏覽器的 Copy 功能,編寫出我們 a標簽的 css 選擇器代碼:div.news-list > ul > li > div.list-hd > h4 > a ,一切都準備好了,我們一起來編寫 Jsoup 方式提取信息的代碼:

          使用 Jsoup 方式提取還是非常簡單的,就5、6行代碼就完成了,關于更多 Jsoup 如何提取節點信息的方法可以參考 jsoup 的官網教程。我們編寫 main 方法,來執行 jsoupList 方法,看看 jsoupList 方法是否正確。

          執行 main 方法,得到如下結果:

          從結果中可以看出,我們已經正確的提取到了我們想要的信息,如果你想采集詳情頁的信息,只需要編寫一個采集詳情頁的方法,在方法中提取詳情頁相應的節點信息,然后將列表頁提取的鏈接傳入提取詳情頁方法即可。httpclient + 正則表達式

          上面我們使用了 Jsoup 方式正確提取了虎撲列表新聞,接下來我們使用 httpclient + 正則表達式的方式來提取,看看使用這種方式又會涉及到哪些問題?httpclient + 正則表達式的方式涉及的知識點還是蠻多的,它涉及到了正則表達式、Java 正則表達式、httpclient。如果你還不知道這些知識,可以點擊下方鏈接簡單了解一下:

          正則表達式:正則表達式

          Java 正則表達式:Java 正則表達式

          httpclient:httpclient

          我們在 pom.xml 文件中,引入 httpclient 相關 Jar 包

          關于虎撲列表新聞頁面,我們在使用 Jsoup 方式的時候進行了簡單的分析,這里我們就不在重復分析了。對于使用正則表達式方式提取,我們需要找到能夠代表列表新聞的結構體,比如:<div class="list-hd"> <h4> <a target="_blank">直上云霄!魔術官方社媒曬富爾茨扣籃炫酷特效圖</a></h4></div>這段結構體,每個列表新聞只有鏈接和標題不一樣,其他的都一樣,而且 <div class="list-hd">是列表新聞特有的。最好不要直接正則匹配 a標簽,因為 a標簽在其他地方也有,這樣我們就還需要做其他的處理,增加我們的難度。現在我們了解了正則結構體的選擇,我們一起來看看 httpclient + 正則表達式方式提取的代碼:

          從代碼的行數可以看出,比 Jsoup 方式要多不少,代碼雖然多,但是整體來說比較簡單,在上面方法中我做了一段特殊處理,我先替換了 httpclient 獲取的字符串 body 中的換行符、制表符、回車符,因為這樣處理,在編寫正則表達式的時候能夠減少一些額外的干擾。接下來我們修改 main 方法,運行 httpClientList 方法。

          運行結果如下圖所示:

          使用 httpclient + 正則表達式的方式同樣正確的獲取到了列表新聞的標題和詳情頁鏈接。到此 Java 爬蟲系列博文第一篇就寫完了,這一篇主要是 Java 網絡爬蟲的入門,我們使用了 jsoup 和 httpclient + 正則的方式提取了虎撲列表新聞的新聞標題和詳情頁鏈接。當然這里還有很多沒有完成,比如采集詳情頁信息存入數據庫等。

          希望以上內容對你有所幫助,下一篇是模擬登陸相關的,如果你對 Java 網絡爬蟲感興趣,不妨關注一波,一起學習,一起進步。

          源代碼:

          正式學習網絡爬蟲之前,我們需要詳細了解 HTTP 的基本原理,了解在瀏覽器中敲入 URL 到獲取網頁內容之間發生了什么。了解這些內容,有助于我們進一步了解爬蟲的基本原理。

          HTTP 基本原理

          在本節中,我們會詳細了解 HTTP 的基本原理,了解在瀏覽器中敲入 URL 到獲取網頁內容之間發生了什么。了解這些內容,有助于我們進一步了解爬蟲的基本原理。

          1. URI 和 URL

          這里我們先了解一下 URI 和 URL。URI 的全稱為 Uniform Resource Identifier,即統一資源標志符;而 URL 的全稱為 Universal Resource Locator,即統一資源定位符。舉例來說,https://github.com/favicon.ico 是一個 URL,也是一個 URI。即有這樣一個圖標資源,我們用 URL/URI 來唯一指定了它的訪問方式,這其中包括了訪問協議 https、訪問路徑(即根目錄)和資源名稱 favicon.ico。通過這樣一個鏈接,我們便可以從互聯網上找到這個資源,這就是 URL/URI。

          URL 是 URI 的子集,也就是說每個 URL 都是 URI,但不是每個 URI 都是 URL。那么,怎樣的 URI 不是 URL 呢?URI 還包括一個子類,叫作 URN,它的全稱為 Universal Resource Name,即統一資源名稱。URN 只命名資源而不指定如何定位資源,比如 urn:isbn:0451450523 指定了一本書的 ISBN,可以唯一標識這本書,但是沒有指定到哪里定位這本書,這就是 URN。URL、URN 和 URI 的關系可以用圖 1-1 表示。

          URL、URN 和 URI 關系圖

          但是在目前的互聯網,URN 使用得非常少,幾乎所有的 URI 都是 URL,所以對于一般的網頁鏈接,我們既可以稱之為 URL,也可以稱之為 URI,我個人習慣稱之為 URL。

          但 URL 也不是隨便寫的,它也是需要遵循一定的格式規范的,基本的組成格式如下:

          scheme://[username:password@]hostname[:port][/path][;parameters][?query][#fragment]

          其中這里中括號包括的內容代表非必要部分,比如 https://www.baidu.com 這個 URL,這里就只包含了 scheme 和 host 兩部分,其他的 port、path、parameters、query、fragment 都沒有。

          這里我們分別介紹下幾部分代表的含義和作用:

          • scheme:協議。比如常用的協議有 http、https、ftp 等等,另外 scheme 也被常稱作 protocol,都代表協議的意思。
          • username、password:用戶名和密碼。在某些情況下 URL 需要提供用戶名和密碼才能訪問,這時候可以把用戶名密碼放在 host 前面。比如 https://ssr3.scrape.center 這個 URL 需要用戶名密碼才能訪問,那么可以直接寫為 https://admin:admin@ssr3.scrape.center 則可以直接訪問。
          • hostname:主機地址。可以是域名或 IP 地址,比如 https://www.baidu.com 這個 URL 中的 hostname 就是 www.baidu.com,這就是百度的二級域名。比如 https://8.8.8.8 這個 URL 中 hostname 就是 8.8.8.8,它是一個 IP 地址。
          • port:端口。這是服務器設定的服務端口,比如 https://8.8.8.8:12345 這個 URL 中的端口就是 12345。但是有些 URL 中沒有端口信息,這是使用了默認的端口,http 協議的默認端口是 80,https 協議的默認端口是 443。所以 https://www.baidu.com 其實相當于 https://www.baidu.com:443,而 http://www.baidu.com 其實相當于 http://www.baidu.com:80。
          • path:路徑。指的是網絡資源在服務器中的指定地址,比如 https://github.com/favicon.ico 這里 path 就是 favicon.ico,指的就是訪問 GitHub 上的根目錄下的 favicon.ico 這個資源。
          • parameters:參數。用來制定訪問某個資源的時候的附加信息,比如 https://8.8.8.8:12345/hello;user 這里的 user 就是 parameters。但是 parameters 現在用得很少,所以目前很多人會把該參數后面的 query 部分稱為參數,甚至把 parameters 和 query 混用。嚴格意義上來說,parameters 是分號 ; 后面的內容。
          • query:查詢。用來查詢某類資源,如果有多個查詢,則用 & 隔開。query 其實非常常見,比如 https://www.baidu.com/s?wd=nba&ie=utf-8,這里的 query 部分就是 wd=nba&ie=utf-8,這里指定了 wd 是 nba,ie 是 utf-8。由于 query 比剛才所說的 parameters 使用頻率高太多,所以平時我們見到的參數、GET 請求參數、parameters、params 等稱呼多數情況指代的也是 query。嚴格意義上來說,其實應該用 query 來表示。
          • fragment:片段。它是對資源描述的部分補充,可以理解為資源內部的書簽。目前它有兩個主要應用,一個是用作單頁面路由,比如 現代前端框架 Vue、React 都可以借助它來做路由管理;另外一個應用是用作 HTML 錨點,用它可以控制一個頁面打開時自動下滑滾動到某個特定的位置。

          以上我們就簡單了解了 URL 的基本概念和構成,后文我們會結合多個實戰案例練習來幫助加深其理解。

          2. HTTP 和 HTTPS

          剛才我們了解了 URL 的基本構成,其支持的協議有很多,比如 http、https、ftp、sftp、smb 等等。

          在爬蟲中,我們抓取的頁面通常基于 http 或 https 協議,這里首先我們先來了解一下這兩個協議的含義。

          HTTP 的全稱是 Hyper Text Transfer Protocol,中文名叫作超文本傳輸協議。HTTP 協議是用于從網絡傳輸超文本數據到本地瀏覽器的傳送協議,它能保證高效而準確地傳送超文本文檔。HTTP 由萬維網協會(World Wide Web Consortium)和 Internet 工作小組 IETF(Internet Engineering Task Force)共同合作制定的規范,目前廣泛使用的是 HTTP 1.1 版本,當然 HTTP 2.0 現在不少網站也增加了支持。

          其發展歷史見下表:

          版本

          產生時間

          主要特點

          發展現狀

          HTTP/0.9

          1991 年

          不涉及數據包傳輸,規定客戶端和服務器之間通信格式,只能 GET 請求

          沒有作為正式的標準

          HTTP/1.0

          1996 年

          傳輸內容格式不限制,增加 PUT、PATCH、HEAD、 OPTIONS、DELETE 命令

          正式作為標準

          HTTP/1.1

          1997 年

          持久連接(長連接)、節約帶寬、HOST 域、管道機制、分塊傳輸編碼

          正式作為標準并廣泛使用

          HTTP/2.0

          2015 年

          多路復用、服務器推送、頭信息壓縮、二進制協議等

          逐漸覆蓋市場

          HTTPS 的全稱是 Hyper Text Transfer Protocol over Secure Socket Layer,是以安全為目標的 HTTP 通道,簡單講是 HTTP 的安全版,即在 HTTP 下加入 SSL 層,簡稱為 HTTPS。

          HTTPS 的安全基礎是 SSL,因此通過它傳輸的內容都是經過 SSL 加密的,它的主要作用分為以下兩種。

          • 建立一個信息安全通道,保證數據傳輸的安全性。
          • 確認網站的真實性。凡是使用了 https 的網站,都可以通過點擊瀏覽器地址欄的鎖頭標志來查看網站認證之后的真實信息,也可以通過 CA 機構頒發的安全簽章來查詢。

          現在越來越多的網站和 App 都已經向 HTTPS 方向發展,舉例如下。

          • 蘋果公司強制所有 iOS App 在 2017 年 1 月 1 日前全部改為使用 HTTPS 加密,否則 App 就無法在應用商店上架。
          • 谷歌從 2017 年 1 月推出的 Chrome 56 開始,對未進行 HTTPS 加密的網址亮出風險提示,即在地址欄的顯著位置提醒用戶 “此網頁不安全”。
          • 騰訊微信小程序的官方需求文檔要求后臺使用 HTTPS 請求進行網絡通信,不滿足條件的域名和協議無法請求。

          因此,HTTPS 已經是大勢所趨。

          注:HTTP 和 HTTPS 協議都屬于計算機網絡中的應用層協議,其下層是基于 TCP 協議實現的,TCP 協議屬于計算機網絡中的傳輸層協議,包括建立連接時的三次握手和斷開時的四次揮手等過程。但本書主要講的是網絡爬蟲相關,主要爬取的是 HTTP/HTTPS 協議相關的內容,所以這里就不再展開深入講解 TCP、IP 等相關知識了,感興趣的讀者可以搜索相關資料了解下,如《計算機網絡》、《圖解 HTTP》等書籍。

          3. HTTP 請求過程

          我們在瀏覽器中輸入一個 URL,回車之后便會在瀏覽器中觀察到頁面內容。

          實際上,這個過程是瀏覽器向網站所在的服務器發送了一個請求,網站服務器接收到這個請求后進行處理和解析,然后返回對應的響應,接著傳回給瀏覽器。

          由于響應里包含頁面的源代碼等內容,瀏覽器再對其進行解析,便將網頁呈現了出來,流程如圖 1-3 所示。

          模型圖

          此處客戶端即代表我們自己的 PC 或手機瀏覽器,服務器即要訪問的網站所在的服務器。

          為了更直觀地說明這個過程,這里用 Chrome 瀏覽器開發者模式下的 Network 監聽組件來做下演示,它可以顯示訪問當前請求網頁時發生的所有網絡請求和響應。

          打開 Chrome 瀏覽器,訪問百度 http://www.baidu.com/,這時候鼠標右鍵并選擇“檢查”菜單(或直接按快捷鍵 F12),即可打開瀏覽器的開發者工具,如下圖所示:

          打開瀏覽器的開發者工具

          我們切換到 Network 面板,然后重新刷新網頁,這時候就可以看到在 Network 面板下方出現了很多個條目,其中一個條目就代表一次發送請求和接收響應的過程,如圖所示:

          請求和接收響應的過程

          我們先觀察第一個網絡請求,即 www.baidu.com,其中各列的含義如下。

          • 第一列 Name:請求的名稱,一般會將 URL 的最后一部分內容當作名稱。
          • 第二列 Status:響應的狀態碼,這里顯示為 200,代表響應是正常的。通過狀態碼,我們可以判斷發送了請求之后是否得到了正常的響應。
          • 第三列 Protocol:請求的協議類型,這里 http/1.1 代表是 HTTP 1.1 版本,h2 代表 HTTP 2.0 版本。
          • 第四列 Type:請求的文檔類型。這里為 document,代表我們這次請求的是一個 HTML 文檔,內容就是一些 HTML 代碼。
          • 第五列 Initiator:請求源。用來標記請求是由哪個對象或進程發起的。
          • 第六列 Size:從服務器下載的文件和請求的資源大小。如果是從緩存中取得的資源,則該列會顯示 from cache。
          • 第七列 Time:發起請求到獲取響應所用的總時間。
          • 第八列 Waterfall:網絡請求的可視化瀑布流。

          我們點擊這個條目,即可看到其更詳細的信息,如圖所示。

          更詳細的信息

          首先是 General 部分,其中 Request URL 為請求的 URL,Request Method 為請求的方法,Status Code 為響應狀態碼,Remote Address 為遠程服務器的地址和端口,Referrer Policy 為 Referrer 判別策略。

          再繼續往下可以看到,有 Response Headers 和 Request Headers,它們分別代表響應頭和請求頭。請求頭里帶有許多請求信息,例如瀏覽器標識、Cookie、Host 等信息,這是請求的一部分,服務器會根據請求頭內的信息判斷請求是否合法,進而作出對應的響應。圖 1-5 中看到的 Response Headers 就是響應的一部分,其中包含了服務器的類型、文檔類型、日期等信息,瀏覽器接收到響應后,會解析響應內容,進而呈現網頁內容。

          下面我們分別來介紹一下請求和響應都包含哪些內容。

          4. 請求(Request)

          請求,英文為 Request,由客戶端向服務器發出,可以分為 4 部分內容:請求方法(Request Method)、請求的網址(Request URL)、請求頭(Request Headers)、請求體(Request Body)。

          下面我們分別予以介紹。

          請求方法(Request Method)

          請求方法,英文為 Request Method,用于標識請求客戶端請求服務端的方式,常見的請求方法有兩種:GET 和 POST。

          在瀏覽器中直接輸入 URL 并回車,這便發起了一個 GET 請求,請求的參數會直接包含到 URL 里。例如,在百度中搜索 Python,這就是一個 GET 請求,鏈接為 https://www.baidu.com/s?wd=Python,其中 URL 中包含了請求的 query 信息,這里的參數 wd 表示要搜尋的關鍵字。POST 請求大多在表單提交時發起。比如,對于一個登錄表單,輸入用戶名和密碼后,點擊 “登錄” 按鈕,這通常會發起一個 POST 請求,其數據通常以表單的形式傳輸,而不會體現在 URL 中。

          GET 和 POST 請求方法有如下區別:

          • GET 請求中的參數包含在 URL 里面,數據可以在 URL 中看到;而 POST 請求的 URL 不會包含這些數據,數據都是通過表單形式傳輸的,會包含在請求體中。
          • GET 請求提交的數據最多只有 1024 字節,而 POST 方式沒有限制。

          一般來說,登錄時,需要提交用戶名和密碼,其中包含了敏感信息,使用 GET 方式請求的話,密碼就會暴露在 URL 里面,造成密碼泄露,所以這里最好以 POST 方式發送。上傳文件時,由于文件內容比較大,也會選用 POST 方式。

          我們平常遇到的絕大部分請求都是 GET 或 POST 請求。另外,還有一些請求方法,如 GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE 等,我們簡單將其總結為下表。

          方 法

          描 述

          GET

          請求頁面,并返回頁面內容

          HEAD

          類似于 GET 請求,只不過返回的響應中沒有具體的內容,用于獲取報頭

          POST

          大多用于提交表單或上傳文件,數據包含在請求體中

          PUT

          從客戶端向服務器傳送的數據取代指定文檔中的內容

          DELETE

          請求服務器刪除指定的頁面

          CONNECT

          把服務器當作跳板,讓服務器代替客戶端訪問其他網頁

          OPTIONS

          允許客戶端查看服務器的性能

          TRACE

          回顯服務器收到的請求,主要用于測試或診斷

          本表參考:http://www.runoob.com/http/http-methods.html。

          請求的網址(Request URL)

          請求的網址,英文為 Reqeust URL,它可以唯一確定我們想請求的資源。關于 URL 的構成和各個部分的功能我們在前文已經提及到了,這里就不再贅述。

          請求頭(Request Headers)

          請求頭,英文為 Request Headers,用來說明服務器要使用的附加信息,比較重要的信息有 Cookie、Referer、User-Agent 等。

          下面簡要說明一些常用的頭信息:

          • Accept:請求報頭域,用于指定客戶端可接受哪些類型的信息。
          • Accept-Language:指定客戶端可接受的語言類型。
          • Accept-Encoding:指定客戶端可接受的內容編碼。
          • Host:用于指定請求資源的主機 IP 和端口號,其內容為請求 URL 的原始服務器或網關的位置。從 HTTP 1.1 版本開始,請求必須包含此內容。
          • Cookie:也常用復數形式 Cookies,這是網站為了辨別用戶進行會話跟蹤而存儲在用戶本地的數據。它的主要功能是維持當前訪問會話。例如,我們輸入用戶名和密碼成功登錄某個網站后,服務器會用會話保存登錄狀態信息,后面我們每次刷新或請求該站點的其他頁面時,會發現都是登錄狀態,這就是 Cookie 的功勞。Cookie 里有信息標識了我們所對應的服務器的會話,每次瀏覽器在請求該站點的頁面時,都會在請求頭中加上 Cookie 并將其發送給服務器,服務器通過 Cookie 識別出是我們自己,并且查出當前狀態是登錄狀態,所以返回結果就是登錄之后才能看到的網頁內容。
          • Referer:此內容用來標識這個請求是從哪個頁面發過來的,服務器可以拿到這一信息并做相應的處理,如做來源統計、防盜鏈處理等。
          • User-Agent:簡稱 UA,它是一個特殊的字符串頭,可以使服務器識別客戶使用的操作系統及版本、瀏覽器及版本等信息。在做爬蟲時加上此信息,可以偽裝為瀏覽器;如果不加,很可能會被識別為爬蟲。
          • Content-Type:也叫互聯網媒體類型(Internet Media Type)或者 MIME 類型,在 HTTP 協議消息頭中,它用來表示具體請求中的媒體類型信息。例如,text/html 代表 HTML 格式,image/gif 代表 GIF 圖片,application/json 代表 JSON 類型,更多對應關系可以查看此對照表:http://tool.oschina.net/commons。

          因此,請求頭是請求的重要組成部分,在寫爬蟲時,大部分情況下都需要設定請求頭。

          請求體(Request Body)

          請求體,即 Request Body 一般承載的內容是 POST 請求中的表單數據,而對于 GET 請求,請求體則為空。

          例如,這里我登錄 GitHub 時捕獲到的請求和響應如圖 1-6 所示。

          請求和響應

          登錄之前,我們填寫了用戶名和密碼信息,提交時這些內容就會以表單數據的形式提交給服務器,此時需要注意 Request Headers 中指定 Content-Type 為 application/x-www-form-urlencoded。只有設置 Content-Type 為 application/x-www-form-urlencoded,才會以表單數據的形式提交。另外,我們也可以將 Content-Type 設置為 application/json 來提交 JSON 數據,或者設置為 multipart/form-data 來上傳文件。

          如下表是 Content-Type 和 POST 提交數據方式的關系

          Content-Type

          提交數據的方式

          application/x-www-form-urlencoded

          表單數據

          multipart/form-data

          表單文件上傳

          application/json

          序列化 JSON 數據

          text/xml

          XML 數據

          在爬蟲中,如果要構造 POST 請求,需要使用正確的 Content-Type,并了解各種請求庫的各個參數設置時使用的是哪種 Content-Type,不然可能會導致 POST 提交后無法正常響應。

          5. 響應(Response)

          響應,即 Response,由服務器返回給客戶端,可以分為三部分:響應狀態碼(Response Status Code)、響應頭(Response Headers)和響應體(Response Body)。

          響應狀態碼(Response Status Code)

          響應狀態碼,即 Response Status Code,表示服務器的響應狀態,如 200 代表服務器正常響應,404 代表頁面未找到,500 代表服務器內部發生錯誤。在爬蟲中,我們可以根據狀態碼來判斷服務器響應狀態,如狀態碼為 200,則證明成功返回數據,再進行進一步的處理,否則直接忽略。下表列出了常見的錯誤代碼及錯誤原因。

          常見的錯誤代碼及錯誤原因

          狀態碼

          說 明

          詳 情

          100

          繼續

          請求者應當繼續提出請求。服務器已收到請求的一部分,正在等待其余部分

          101

          切換協議

          請求者已要求服務器切換協議,服務器已確認并準備切換

          200

          成功

          服務器已成功處理了請求

          201

          已創建

          請求成功并且服務器創建了新的資源

          202

          已接受

          服務器已接受請求,但尚未處理

          203

          非授權信息

          服務器已成功處理了請求,但返回的信息可能來自另一個源

          204

          無內容

          服務器成功處理了請求,但沒有返回任何內容

          205

          重置內容

          服務器成功處理了請求,內容被重置

          206

          部分內容

          服務器成功處理了部分請求

          300

          多種選擇

          針對請求,服務器可執行多種操作

          301

          永久移動

          請求的網頁已永久移動到新位置,即永久重定向

          302

          臨時移動

          請求的網頁暫時跳轉到其他頁面,即暫時重定向

          303

          查看其他位置

          如果原來的請求是 POST,重定向目標文檔應該通過 GET 提取

          304

          未修改

          此次請求返回的網頁未修改,繼續使用上次的資源

          305

          使用代理

          請求者應該使用代理訪問該網頁

          307

          臨時重定向

          請求的資源臨時從其他位置響應

          400

          錯誤請求

          服務器無法解析該請求

          401

          未授權

          請求沒有進行身份驗證或驗證未通過

          403

          禁止訪問

          服務器拒絕此請求

          404

          未找到

          服務器找不到請求的網頁

          405

          方法禁用

          服務器禁用了請求中指定的方法

          406

          不接受

          無法使用請求的內容響應請求的網頁

          407

          需要代理授權

          請求者需要使用代理授權

          408

          請求超時

          服務器請求超時

          409

          沖突

          服務器在完成請求時發生沖突

          410

          已刪除

          請求的資源已永久刪除

          411

          需要有效長度

          服務器不接受不含有效內容長度標頭字段的請求

          412

          未滿足前提條件

          服務器未滿足請求者在請求中設置的其中一個前提條件

          413

          請求實體過大

          請求實體過大,超出服務器的處理能力

          414

          請求 URI 過長

          請求網址過長,服務器無法處理

          415

          不支持類型

          請求格式不被請求頁面支持

          416

          請求范圍不符

          頁面無法提供請求的范圍

          417

          未滿足期望值

          服務器未滿足期望請求標頭字段的要求

          500

          服務器內部錯誤

          服務器遇到錯誤,無法完成請求

          501

          未實現

          服務器不具備完成請求的功能

          502

          錯誤網關

          服務器作為網關或代理,從上游服務器收到無效響應

          503

          服務不可用

          服務器目前無法使用

          504

          網關超時

          服務器作為網關或代理,但是沒有及時從上游服務器收到請求

          505

          HTTP 版本不支持

          服務器不支持請求中所用的 HTTP 協議版本

          響應頭(Response Headers)

          響應頭,即 Response Headers,包含了服務器對請求的應答信息,如 Content-Type、Server、Set-Cookie 等。下面簡要說明一些常用的頭信息。

          • Date:標識響應產生的時間。
          • Last-Modified:指定資源的最后修改時間。
          • Content-Encoding:指定響應內容的編碼。
          • Server:包含服務器的信息,比如名稱、版本號等。
          • Content-Type:文檔類型,指定返回的數據類型是什么,如 text/html 代表返回 HTML 文檔,application/x-javascript 則代表返回 JavaScript 文件,image/jpeg 則代表返回圖片。
          • Set-Cookie:設置 Cookie。響應頭中的 Set-Cookie 告訴瀏覽器需要將此內容放在 Cookie 中,下次請求攜帶 Cookie 請求。
          • Expires:指定響應的過期時間,可以使代理服務器或瀏覽器將加載的內容更新到緩存中。如果再次訪問時,就可以直接從緩存中加載,降低服務器負載,縮短加載時間。

          響應體(Response Body)

          響應體,即 Response Body,這可以說是最關鍵的部分了,響應的正文數據都在響應體中,比如請求網頁時,它的響應體就是網頁的 HTML 代碼;請求一張圖片時,它的響應體就是圖片的二進制數據。我們做爬蟲請求網頁后,要解析的內容就是響應體,如圖 1-7 所示。

          響應體

          在瀏覽器開發者工具中點擊 Preview,就可以看到網頁的源代碼,也就是響應體的內容,它是解析的目標。

          在做爬蟲時,我們主要通過響應體得到網頁的源代碼、JSON 數據等,然后從中做相應內容的提取。

          本節中,我們了解了 HTTP 的基本原理,大概了解了訪問網頁時背后的請求和響應過程。本節涉及的知識點需要好好掌握,后面分析網頁請求時會經常用到。

          6. HTTP/2.0

          前面我們也提到了 HTTP 協議從 2015 年起發布了 2.0 版本,相比 HTTP/1.1 來說,HTTP/2.0 變得更快、更簡單、更穩定,HTTP/2.0 在傳輸層做了很多優化,HTTP/2.0 的主要目標是通過支持完整的請求與響應復用來減少延遲,并通過有效壓縮 HTTP 請求頭字段將協議開銷降至最低,同時增加對請求優先級和服務器推送的支持,這些優化一筆勾銷了 HTTP/1.1 為做傳輸優化想出的一系列“歪招”。

          有讀者這時候可能會問,為什么不叫 HTTP/1.2 而叫 HTTP/2.0 呢?因為 HTTP/2.0 在內部實現上新的二進制分幀層,這是沒法與之前的 HTTP/1.x 的服務器和客戶端實現向后兼容的,所以直接修改了主版本號為 2.0。

          下面我們就來了解下 HTTP/2.0 相比 HTTP/1.1 來說做了哪些優化吧。

          二進制分幀層

          HTTP/2.0 所有性能增強的核心就在于這個新的二進制分幀層。在 HTTP/1.x 中,不管是請求(Request)還是響應(Response),它們都是用文本格式傳輸的,其頭部(Headers)、實體(Body)之間也是用文本換行符分隔開的。HTTP/2.0 對其做了優化,將文本格式修改為了二進制格式,使得解析起來更加高效。同時將請求和響應數據分割為更小的幀,并采用二進制編碼。

          所以這里就引入了幾個新的概念:

          • 幀:只存在于 HTTP/2.0 中的概念,是數據通信的最小單位,比如一個請求被分為了請求頭幀(Request Headers frame)和請求體/數據幀(Request Data frame)。
          • 數據流:一個虛擬通道,可以承載雙向的消息,每個流都有一個唯一的整數 ID 來標識。
          • 消息:與邏輯請求或響應消息對應的完整的一系列幀。

          在 HTTP/2.0 中,同域名下的所有通信都可以在單個連接上完成,該連接可以承載任意數量的雙向數據流,數據流是用于承載雙向消息的,每條消息都是一條邏輯 HTTP 消息(例如請求或響應),它可以包含一個或多個幀。

          簡而言之,HTTP/2.0 將 HTTP 協議通信分解為二進制編碼幀的交換,這些幀對應著特定數據流中的消息,所有這些都在一個 TCP 連接內復用,這是 HTTP/2.0 協議所有其他功能和性能優化的基礎。

          多路復用

          在 HTTP/1.x 中,如果客戶端要想發起多個并行請求以提升性能,則必須使用多個 TCP 連接,而且瀏覽器位了控制資源,還會對單個域名有 6-8 個 TCP 連接請求的限制。但在 HTTP/2.0 中,由于又了二進制分幀技術的加持,HTTP/2.0 不用再以來 TCP 連接去實現多路并行了,客戶端和服務器可以將 HTTP 消息分解為互不依賴的幀,然后交錯發送,最后再在另一端把它們重新組裝起來,讓我們可以:

          • 并行交錯地發送多個請求,請求之間互不影響。
          • 并行交錯地發送多個響應,響應之間互不干擾。
          • 使用一個連接并行發送多個請求和響應。
          • 不必再為繞過 HTTP/1.x 限制而做很多工作。
          • 消除不必要的延遲和提高現有網絡容量的利用率,從而減少頁面加載時間。

          這樣以來,整個數據傳輸使性能就有了極大提升:

          • 同個域名只需要占用一個 TCP 連接,使用一個連接并行發送多個請求和響應,消除了因多個 TCP 連接而帶來的延時和內存消耗。
          • 并行交錯地發送多個請求和詳情,而且之間互不影響。
          • 在 HTTP/2.0 中,每個請求都可以帶一個 31bit 的優先值,0 表示最高優先級, 數值越大優先級越低。有了這個優先值,客戶端和服務器就可以在處理不同的流時采取不同的策略,以最優的方式發送流、消息和幀。

          流量控制

          流控制是一種阻止發送方向接收方發送大量數據的機制,以免超出后者的需求或處理能力。可以理解為,接收方已經太繁忙了,來不及處理收到的消息了,但是發送方還在一直大量發送消息,這樣就會出現一些問題。

          比如說,客戶端可能請求了一個具有較高優先級的大型視頻流,但是用戶已經暫停視頻,客戶端現在希望暫停或限制從服務器的傳輸,以免提取和緩沖不必要的數據。 再比如,一個代理服務器可能具有較快的下游連接和較慢的上游連接,并且也希望調節下游連接傳輸數據的速度以匹配上游連接的速度來控制其資源利用率等等。

          由于 HTTP 是基于 TCP 實現的,雖然 TCP 原生有流量控制機制,但是由于 HTTP/2.0 數據流在一個 TCP 連接內復用,TCP 流控制既不夠精細,也無法提供必要的應用級 API 來調節各個數據流的傳輸。

          為了解決這一問題,HTTP/2.0 提供了一組簡單的構建塊,這些構建塊允許客戶端和服務器實現其自己的數據流和連接級流控制:

          • 流控制具有方向性。 每個接收方都可以根據自身需要選擇為每個數據流和整個連接設置任意的窗口大小。
          • 流控制基于信用。 每個接收方都可以公布其初始連接和數據流流控制窗口(以字節為單位),每當發送方發出 DATA 幀時都會減小,在接收方發出 WINDOW_UPDATE 幀時增大。
          • 流控制無法停用。 建立 HTTP/2.0 連接后,客戶端將與服務器交換 SETTINGS 幀,這會在兩個方向上設置流控制窗口。 流控制窗口的默認值設為 65535 字節,但是接收方可以設置一個較大的最大窗口大小(2^31-1 字節),并在接收到任意數據時通過發送 WINDOW_UPDATE 幀來維持這一大小。
          • 流控制為逐躍點控制,而非端到端控制。 即,可信中介可以使用它來控制資源使用,以及基于自身條件和啟發式算法實現資源分配機制。

          由此可見,HTTP/2.0 提供了簡單的構建塊實現了自定義策略來調節資源使用和分配,以及實現新傳輸能力,同時提升了網頁應用的實際性能和感知性能。

          服務端推送

          HTTP/2.0 新增的另一個強大的新功能是,服務器可以對一個客戶端請求發送多個響應。 換句話說,除了對最初請求的響應外,服務器還可以向客戶端推送額外資源,而無需客戶端明確地請求。

          如果某些資源客戶端是一定會請求的,這時就可以采取服務端推送的技術,在客戶端發起一次請求后,額外提前給客戶端推送必要的資源,這樣就可以相對減少一點延遲時間。例如,服務端可以主動把 JS 和 CSS 文件推送給客戶端,而不需要客戶端解析 HTML 時再發送這些請求。

          服務端推送

          服務端可以主動推送,當然客戶端也有權利選擇是否接收。如果服務端推送的資源已經被瀏覽器緩存過,瀏覽器可以通過發送 RST_STREAM 幀來拒收。

          另外主動推送也遵守同源策略,即服務器不能隨便將第三方資源推送給客戶端,而必須是經過雙方確認才行,這樣也能保證一定的安全性。

          HTTP/2.0 發展現狀

          HTTP/2.0 的普及是一件任重而道遠的事情,一些主流的網站現在已經支持了 HTTP/2.0,主流瀏覽器現在都已經實現了 HTTP/2.0 的支持,但總的來看,目前大部分網站依然還是以 HTTP/1.1 為主。

          另外一些編程語言的庫還沒有完全支持 HTTP/2.0,比如對于 Python 來說,hyper、httpx 等庫已經支持了 HTTP/2.0,但廣泛使用的 requests 庫依然還是只支持 HTTP/1.1。

          7. 總結

          本節介紹了關于 HTTP 的一些基礎知識,內容不少,需要好好掌握,這些知識對于后面我們編寫和理解網絡爬蟲具有非常大的幫助。

          由于本節的內容多數為概念介紹,內容參考了很多書籍、文檔、博客,來源如下:

          • 書籍 - 《HTTP 權威指南》- 作者 David Gourley / Brian Totty
          • 文檔 - HTTP - 維基百科:https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
          • 文檔 - HTTP - 百度百科:https://baike.baidu.com/item/HTTP/243074
          • 文檔 - HTTP - MDN Web Docs:https://developer.mozilla.org/en-US/docs/Web/HTTP
          • 文檔 - HTTP/2 簡介 - Google 開發文檔:https://developers.google.com/web/fundamentals/performance/http2
          • 博客 - 一文讀懂 HTTP/2 及 HTTP/3 特性:https://blog.fundebug.com/2019/03/07/understand-http2-and-http3/
          • 博客 - 一文讀懂 HTTP/2 特性:https://zhuanlan.zhihu.com/p/26559480

          主站蜘蛛池模板: 国产一区二区三区在线免费| 日本无码一区二区三区白峰美 | 日本无码一区二区三区白峰美| 精品国产乱子伦一区二区三区 | 一区免费在线观看| 亚洲综合国产一区二区三区| 国产MD视频一区二区三区| 精品爆乳一区二区三区无码av| 国产精品一区二区久久| 国产高清精品一区| 国产成人午夜精品一区二区三区| 久久久久成人精品一区二区| 亚洲乱码日产一区三区| 狠狠综合久久AV一区二区三区 | 免费日本一区二区| 国产vr一区二区在线观看| 高清一区二区三区视频| 日韩精品一区二区三区中文字幕| 精产国品一区二区三产区| 亚洲综合在线一区二区三区| 久久精品亚洲一区二区三区浴池| 日产一区日产2区| 亚洲福利电影一区二区?| 精品动漫一区二区无遮挡| 国产一区二区三区韩国女主播| 日本在线视频一区二区| 色老头在线一区二区三区| 日韩免费视频一区| 暖暖免费高清日本一区二区三区| 无码国产精品一区二区免费式影视| 熟妇人妻AV无码一区二区三区| 国模私拍一区二区三区| 国产精品无码一区二区在线观| 精品国产一区二区三区久久久狼 | 午夜福利av无码一区二区| 无码少妇精品一区二区免费动态| 亚洲一区二区三区高清视频| 日韩精品一区二区三区色欲AV | 久久综合精品不卡一区二区| 久久久久人妻一区精品色| 韩国美女vip福利一区|