1. 程式人生 > >潭州課堂25班:Ph201805201 爬蟲基礎 第一課 (課堂筆記)

潭州課堂25班:Ph201805201 爬蟲基礎 第一課 (課堂筆記)

這一 變化 提交數據 http 正常的 分類 求和 風險 tls

爬蟲的概念:

其實呢,爬蟲更官方點的名字叫數據采集,英文一般稱作spider,就是通過編程來全自動的從互聯網上采集數據。
比如說搜索引擎就是一種爬蟲。
爬蟲需要做的就是模擬正常的網絡請求,比如你在網站上點擊一個網址,就是一次網絡請求。

爬蟲的作用:

現如今大數據時代已經到來,網絡爬蟲技術成為這個時代不可或缺的一部分,企業需要數據來分析用戶行為,來分析自己產品的不足之處,來分析競爭對手的信息等等,但是這些的首要條件就是數據的采集。
這其中使用爬蟲較為有名的有今日頭條等公司。

爬蟲的本質

爬蟲的本質就是自動化的去模擬正常人類發起的網絡請求,然後獲取網絡請求所返回的數據。
跟我們人手動去點擊一個連接,訪問一個網頁獲取數據,並沒有什麽本質的區別。

爬蟲的難點

爬蟲的難點主要為兩個方向:
數據的獲取
一般來說我們想要抓取的網站是不希望我們去抓取他的數據的,那麽這些網站就會做一些反爬蟲的措施,來讓我們無法去他的網站上抓取數據。所以我們也要做相應的措施去繞過這些反爬蟲措施。
抓取數據的速度
我們抓取的目標的數據量,有時是非常龐大的,甚至幾千萬上億的數據量,而有些甚至會要求實時的更新,所以抓取的速度也非常重要。我們一般會使用並發和分布式來解決速度的問題。

網絡請求

網絡請求其實就是在互聯網上一次數據的傳遞。

而為了數據能夠在龐雜的網絡中能夠正確,迅速的傳遞給目標主機。我們定義了許多的網絡協議,也就是網絡傳輸數據的規則,來實現網絡的連接。

而這些協議中,我們使用的最多的,基本上就是HTTP/HTTPS協議。

技術分享圖片

技術分享圖片

HTTP協議最大的缺點就是明文傳輸,而在網絡上數據傳輸的路徑上有很大一部分都是暴露在公有環境下的,所以數據是很容易泄露。

技術分享圖片

因為HTTP的這個缺點,所以就出現了基於SSL或者TSL的HTTPS協議。

在HTTPS請求發起之前,客戶端會首先向服務端發起請求,獲取證書。HTTPS傳輸的數據是經過證書加密以後的數據,這就避免了數據泄露的風險。

HTTPS保證了安全性的同時,也降低了傳輸的速度,協議的速度比HTTP慢大概2-100倍。

技術分享圖片


WebSocket是HTML5開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。
由於HTTP 協議是一種無狀態的、無連接的、單向的應用層協議。它采用了請求/響應模型。通信請求只能由客戶端發起,服務端對請求做出應答處理。

這種通信模型有一個弊端:HTTP 協議無法實現服務器主動向客戶端發起消息。
這種單向請求的特點,註定了如果服務器有連續的狀態變化,客戶端要獲知就非常麻煩。大多數 Web 應用程序將通過頻繁請求實現長輪詢。輪詢的效率低,非常浪費資源(因為必須不停連接,或者 HTTP 連接始終打開)。

在WebSocket API中,瀏覽器和服務器只需要做一個握手的動作,然後,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。
瀏覽器向服務器發出建立 WebSocket 連接的請求,連接建立以後,客戶端和服務器端就可以通過 TCP 連接直接交換數據。
由於websocket出現的時間較短,應用的範圍比較小,所以使用的較少。

# 深入淺出了解HTTP協議

![timg](深入淺出了解HTTP協議.assets/timg.jpg)

HTTP(HyperText Transfer Protocol,超文本傳輸協議)是互聯網上應用最為廣泛的一種網絡協議。目前使用最普遍的一個版本是HTTP 1.1。

HTTP協議是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先於圖形)等。

## HTTP協議簡介

**HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型。**

一次HTTP請求的基本流程一般是,在建立TCP連接後,由客戶端向服務端發起一次請求(request),而服務器在接收到以後返回給客戶端一個響應(response)。

所以我們看到的HTTP請求內容一般就分為請求和響應兩部分。

HTTP協議通常承載於TCP協議之上,有時也承載於TLS或SSL協議層之上,這個時候,就成了我們常說的HTTPS。

默認HTTP的端口號為80。

**HTTP是一個無狀態的協議。**

### 無狀態協議

HTTP協議是無狀態的,也就是說每一次HTTP請求之間都是相互獨立的,沒有聯系的,服務端不知道客戶端具體的狀態。

比如客戶端訪問一次網頁之後關閉瀏覽器,然後再一次啟動瀏覽器,再訪問該網站,服務器是不知道客戶關閉了一次瀏覽器的。

這樣設計的原因是因為Web服務器一般需要面對很多瀏覽器的並發訪問,為了提高Web服務器對並發訪問的處理能力,在設計HTTP協議時規定Web服務器發送HTTP應答報文和文檔時,不保存發出請求的Web瀏覽器進程的任何狀態信息。

## HTTP請求

每一個HTTP請求都由三部分組成,分別是:請求行、請求報頭、請求正文。

### 請求行

請求行一般由**請求方法**、**url路徑**、**協議版本**組成,如下所示:

![image-20180607170241105](深入淺出了解HTTP協議.assets/image-20180607170241105.png)

### 請求報頭

請求行下方的是則是請求報頭,HTTP消息報頭包括普通報頭、請求報頭、響應報頭、實體報頭。每個報頭的形式如下:

```
名字 + : + 空格 + 值
```

- **Host**

指定的請求資源的域名(主機和端口號)。HTTP請求必須包含HOST,否則系統會以400狀態碼返回。

- **User-Agant**

簡稱UA,內容包含發出請求的用戶信息,通常UA包含瀏覽者的信息,主要是瀏覽器的名稱版本和所用的操作系統。這個UA頭不僅僅是使用瀏覽器才存在,只要使用了基於HTTP協議的客戶端軟件都會發送,無論是手機端還是PDA等,這個UA頭是辨別客戶端所用設備的重要依據。

- **Accept**

告訴服務器可以接受的文件格式。通常這個值在各種瀏覽器中都差不多,不過WAP瀏覽器所能接受的格式要少一些,這也是用來區分WAP和計算機瀏覽器的主要依據之一,隨著WAP瀏覽器的升級,其已經和計算機瀏覽器越來越接近,因此這個判斷所起的作用也越來越弱。

- **Cookie**

Cookie信息。

- **Cache-Control**

指定請求和響應遵循的緩存機制。在請求消息或響應消息中設置Cache-Control並不會修改另一個消息消息處理過程中的緩存處理過程。請求時的緩存指令包括no-cache、no-store、man-age、max-stake、min-fresh、only-if-cached;響應消息中的指令包括 public、privete、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。

- **Referer**

頁面跳轉處,表明產生請求的網頁來自於哪個URL,用戶是從該 Referer頁面訪問到當前請求的頁面。這個屬性可以用來跟蹤Web請求來自哪個頁面,是從什麽網站來的。

- **Content-Length**

內容長度。

- **Content-Range**

響應的資源範圍。可以在每次請求中標記請求的資源範圍,在連接斷開重連時,客戶端只請求該資源未下載的部分,而不是重新請求整個資源,實現斷點續傳。迅雷就是基於這個原,使用多線程分段讀取網絡上的資源,最後再合並。

- **Accept-Encoding**

指定所能接收的編碼方式,通常服務器會對頁面進行GZIP壓縮後再輸出以減少流量,一般瀏覽器均支持對這種壓縮後的數據進行處理,但對於我們來說,如果不想接收到這些看似亂碼的數據,可以指定不接收任何服務器端壓縮處理,要求其原樣返回。

- **Accept-Language**

指瀏覽器可以接受的語言種類 en、en-us指英語 zh、zh-cn指中文。

- **Connection**

客戶端與服務器鏈接類型,keep-alive:保持鏈接,close:關閉鏈接。

### 請求正文

請求正文通常是使用POST方法進行發送的數據,GET方法是沒有請求正文的。

請求正文跟上面的消息報頭一般由一個空行隔開。

## HTTP響應

HTTP響應同樣也是由狀態行、響應報頭、報文主體三部分組成。

### 狀態行

狀態行由HTTP協議版本號, 狀態碼, 狀態消息三部分組成。如下所示:

![image-20180608145413903](深入淺出了解HTTP協議.assets/image-20180608145413903.png)

### 響應報頭

- **Allow**

服務器支持哪些請求方法(如GET、POST等)。

- **Date**

表示消息發送的時間,時間的描述格式由rfc822定義。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的時間表示世界標準時,換算成本地時間,需要知道用戶所在的時區。

- **Set-Cookie**

非常重要的header, 用於把cookie發送到客戶端瀏覽器,每一個寫入cookie都會生成一個Set-Cookie。

- **Expires**

指明應該在什麽時候認為文檔已經過期,從而不再緩存它,重新從服務器獲取,會更新緩存。過期之前使用本地緩存。

- **Content-Type**

WEB服務器告訴客戶端自己響應的對象的類型和字符集。

- **Content-Encoding**

文檔的編碼(Encode)方法。只有在解碼之後才可以得到Content-Type頭指定的內容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時間。

- **Content-Length**

指明實體正文的長度,以字節方式存儲的十進制數字來表示。

- **Location**

用於重定向一個新的位置,包含新的URL地址。表示客戶應當到哪裏去提取文檔。

- **Refresh**

表示瀏覽器應該在多少時間之後刷新文檔,以秒計。

### 響應正文

服務器返回的數據。

## URL

URL(Uniform Resource Locator),中文叫統一資源定位符。是用來標識某一處資源的地址。以下面這個URL為例,介紹下普通URL的各部分組成:

![image-20180607140712008](深入淺出了解HTTP協議.assets/image-20180607140712008.png)

1. 協議部分:該URL的協議部分為“http:”,這代表網頁使用的是HTTP協議。在"HTTP"後面的“//”為分隔符。

2. 域名部分:該URL的域名部分為“www.aspxfans.com”。一個URL中,也可以使用IP地址作為域名使用。

3. 端口部分:跟在域名後面的是端口,域名和端口之間使用“:”作為分隔符。端口不是一個URL必須的部分,如果省略端口部分,將采用默認端口。

4. 路徑部分:從域名後的第一個“/”開始到最後一個“?”為止,是路徑部分,如果沒有“?”,則是從域名後的最後一個“/”開始到“#”為止,是路徑部分,如果沒有“?”和“#”,那麽從域名後的最後一個“/”開始到結束,都是路徑部分。

本例中的文件名是“index.asp”。文件名部分也不是一個URL必須的部分,如果省略該部分,則使用默認的文件名。

5. 參數部分:從“?”開始到“#”為止之間的部分為參數部分。本例中的參數部分為“boardID=5&ID=24618&page=1”。參數可以允許有多個參數,參數與參數之間用“&”作為分隔符。

6. 錨部分:從“#”開始到最後,都是錨部分。本例中的錨部分是“name”。錨部分也不是一個URL必須的部分。

錨部分是用來定位到頁面中某個元素的。

## HTTP請求方法

HTTP協議中定義的請求方法有以下幾種:

| 序號 | 方法 | 描述 |
| ---- | ------- | ------------------------------------------------------------ |
| 1 | GET | 請求指定的頁面信息,並返回實體主體。 |
| 2 | HEAD | 類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭 |
| 3 | POST | 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。 |
| 4 | PUT | 從客戶端向服務器傳送的數據取代指定的文檔的內容。 |
| 5 | DELETE | 請求服務器刪除指定的頁面。 |
| 6 | CONNECT | HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。 |
| 7 | OPTIONS | 允許客戶端查看服務器的性能。 |
| 8 | TRACE | 回顯服務器收到的請求,主要用於測試或診斷。 |

雖然HTTP請求中定義的方法有這麽多種,但是我們平常使用的基本只有`GET`和`POST`兩種方法,而且大部分網站都是禁用掉了除`GET`和`POST`外其他的方法。

因為其他幾種方法通過`GET`或者`POST`都能實現,而且對於網站來說更加的安全和可控。

- `GET`

其實簡單來說,`GET`方法一般用來負責獲取數據,或者將一些簡短的數據放到URL參數中傳遞到服務器。比`POST`更加高效和方便。

- `POST`

由於`GET`方法最多在url中攜帶1024字節數據,且將數據放到URL中傳遞太不安全,數據量大時URL也會變得冗長。所以傳遞數據量大或者安全性要求高的數據的時候,最好使用`POST`方法來傳遞數據。

## 狀態碼(status code)

當客戶端向服務端發起一次請求後,服務端在返回的響應頭中會包含一個HTTP狀態碼。下面是一些常見的狀態碼:

- 200 - 請求成功

- 301 - 資源(網頁等)被永久轉移到其它URL

- 404 - 請求的資源(網頁等)不存在

- 500 - 內部服務器錯誤

HTTP的狀態碼是由三位數字來表示的,由第一位數字來表示狀態碼的類型,一般來說有五種類型:

| 分類 | 分類描述 |
| ---- | ---------------------------------------------- |
| 1** | 信息,服務器收到請求,需要請求者繼續執行操作 |
| 2** | 成功,操作被成功接收並處理 |
| 3** | 重定向,需要進一步的操作以完成請求 |
| 4** | 客戶端錯誤,請求包含語法錯誤或無法完成請求 |
| 5** | 服務器錯誤,服務器在處理請求的過程中發生了錯誤 |

以下是詳細的狀態碼列表:

| 狀態碼 | 狀態碼英文名稱 | 中文描述 |
| ------ | ------------------------------- | ------------------------------------------------------------ |
| 100 | Continue | 繼續。[客戶端](http://www.dreamdu.com/webbuild/client_vs_server/)應繼續其請求 |
| 101 | Switching Protocols | 切換協議。服務器根據客戶端的請求切換協議。只能切換到更高級的協議,例如,切換到HTTP的新版本協議 |
| | | |
| 200 | OK | 請求成功。一般用於GET與POST請求 |
| 201 | Created | 已創建。成功請求並創建了新的資源 |
| 202 | Accepted | 已接受。已經接受請求,但未處理完成 |
| 203 | Non-Authoritative Information | 非授權信息。請求成功。但返回的meta信息不在原始的服務器,而是一個副本 |
| 204 | No Content | 無內容。服務器成功處理,但未返回內容。在未更新網頁的情況下,可確保瀏覽器繼續顯示當前文檔 |
| 205 | Reset Content | 重置內容。服務器處理成功,用戶終端(例如:瀏覽器)應重置文檔視圖。可通過此返回碼清除瀏覽器的表單域 |
| 206 | Partial Content | 部分內容。服務器成功處理了部分GET請求 |
| | | |
| 300 | Multiple Choices | 多種選擇。請求的資源可包括多個位置,相應可返回一個資源特征與地址的列表用於用戶終端(例如:瀏覽器)選擇 |
| 301 | Moved Permanently | 永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的URI,瀏覽器會自動定向到新URI。今後任何新的請求都應使用新的URI代替 |
| 302 | Found | 臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI |
| 303 | See Other | 查看其它地址。與301類似。使用GET和POST請求查看 |
| 304 | Not Modified | 未修改。所請求的資源未修改,服務器返回此狀態碼時,不會返回任何資源。客戶端通常會緩存訪問過的資源,通過提供一個頭信息指出客戶端希望只返回在指定日期之後修改的資源 |
| 305 | Use Proxy | 使用代理。所請求的資源必須通過代理訪問 |
| 306 | Unused | 已經被廢棄的HTTP狀態碼 |
| 307 | Temporary Redirect | 臨時重定向。與302類似。使用GET請求重定向 |
| | | |
| 400 | Bad Request | 客戶端請求的語法錯誤,服務器無法理解 |
| 401 | Unauthorized | 請求要求用戶的身份認證 |
| 402 | Payment Required | 保留,將來使用 |
| 403 | Forbidden | 服務器理解請求客戶端的請求,但是拒絕執行此請求 |
| 404 | Not Found | 服務器無法根據客戶端的請求找到資源(網頁)。通過此代碼,網站設計人員可設置"您所請求的資源無法找到"的個性頁面 |
| 405 | Method Not Allowed | 客戶端請求中的方法被禁止 |
| 406 | Not Acceptable | 服務器無法根據客戶端請求的內容特性完成請求 |
| 407 | Proxy Authentication Required | 請求要求代理的身份認證,與401類似,但請求者應當使用代理進行授權 |
| 408 | Request Time-out | 服務器等待客戶端發送的請求時間過長,超時 |
| 409 | Conflict | 服務器完成客戶端的PUT請求是可能返回此代碼,服務器處理請求時發生了沖突 |
| 410 | Gone | 客戶端請求的資源已經不存在。410不同於404,如果資源以前有現在被永久刪除了可使用410代碼,網站設計人員可通過301代碼指定資源的新位置 |
| 411 | Length Required | 服務器無法處理客戶端發送的不帶Content-Length的請求信息 |
| 412 | Precondition Failed | 客戶端請求信息的先決條件錯誤 |
| 413 | Request Entity Too Large | 由於請求的實體過大,服務器無法處理,因此拒絕請求。為防止客戶端的連續請求,服務器可能會關閉連接。如果只是服務器暫時無法處理,則會包含一個Retry-After的響應信息 |
| 414 | Request-URI Too Large | 請求的URI過長(URI通常為網址),服務器無法處理 |
| 415 | Unsupported Media Type | 服務器無法處理請求附帶的媒體格式 |
| 416 | Requested range not satisfiable | 客戶端請求的範圍無效 |
| 417 | Expectation Failed | 服務器無法滿足Expect的請求頭信息 |
| | | |
| 500 | Internal Server Error | 服務器內部錯誤,無法完成請求 |
| 501 | Not Implemented | 服務器不支持請求的功能,無法完成請求 |
| 502 | Bad Gateway | 充當網關或代理的服務器,從遠端服務器接收到了一個無效的請求 |
| 503 | Service Unavailable | 由於超載或系統維護,服務器暫時的無法處理客戶端的請求。延時的長度可包含在服務器的Retry-After頭信息中 |
| 504 | Gateway Time-out | 充當網關或代理的服務器,未及時從遠端服務器獲取請求 |
| 505 | HTTP Version not supported | 服務器不支持請求的HTTP協議的版本,無法完成處理 |

## Cookie

`Cookie`有時也用其復數形式 `Cookies`,英文是餅幹的意思。指某些網站為了辨別用戶身份、進行 session 跟蹤而儲存在用戶本地終端上的數據(通常經過加密)。最新的規範是 RFC6265 。

`Cookie`其實就是由服務器發給客戶端的特殊信息,而這些信息以文本文件的方式存放在客戶端,然後客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息。 服務器在接收到`Cookie`以後,會驗證`Cookie`的信息,以此來辨別用戶的身份。

`Cookie`可以理解為一個臨時通行證。

### 作用

`Cookie`其實是HTTP請求頭的擴展部分,由於HTTP協議是無狀態的協議,所以為了在網頁上實現登陸之類的需求,所以擴展了`Cookie`這樣的功能。

每一次HTTP請求在數據交換完畢之後就會關閉連接,所以下一次HTTP請求就無法讓服務端得知你和上一次請求的關系。而使用了`Cookie`之後,你在第一次登陸之類的請求成功之後,服務器會在`Response`的頭信息中給你返回`Cookie`信息,你下一次訪問的時候帶上這個Cookie信息,則服務器就能識別你為上一次成功登陸的用戶。

### 內容

`Cookie`一般保存的格式為json格式,由一些屬性組成。

- name:`Cookie`的名稱
- value:`Cookie`的值
- domain:可以使用此`Cookie`的域名
- path:可以使用此`Cookie`的頁面路徑
- expires/Max-Age:此`Cookie`的超時時間
- secure:設置是否只能通過https來傳遞此條`Cookie`

### domain屬性

域名一般來說分為頂級域名,二級域名,三級域名等等。

例如baidu.com是一個頂級域名,而www.baidu.com和map.baidu.com就是二級域名,依次類推。

而在我們的`Cookie`來說,都有一個`domain`屬性,這個屬性限制了訪問哪些域名時可以使用這一條`Cookie`。因為每個網站基本上都會分發`Cookie`,所以`domain`屬性就可以讓我們在訪問新浪時不會帶上百度分發給我們的`Cookie`。

而在同一系的域名中,頂級域名是無法使用其二級域名的`Cookie`的,也就是說訪問baidu.com的時候是不會帶上map.baidu.com分發的`Cookie`的,二級域名之間的`Cookie`也不可以共享。但訪問二級域名時是可以使用頂級域名的`Cookie`的。

### path屬性

path屬性為可以訪問此cookie的頁面路徑。 比如domain是abc.com,path是/test,那麽只有/test路徑下的頁面可以讀取此cookie。

### expires/Max-Age屬性

字段為此cookie超時時間。若設置其值為一個時間,那麽當到達此時間後,此cookie失效。不設置的話默認值是Session,意思是cookie會和session一起失效。當瀏覽器關閉(不是瀏覽器標簽頁,而是整個瀏覽器) 後,此cookie失效。

## Session

Session,中文經常翻譯為會話,其本來的含義是指有始有終的一系列動作/消息,比如打電話時從拿起電話撥號到掛斷電話這中間的一系列過程可以稱之為一個session。這個詞在各個領域都有在使用。

而我們web領域,一般使用的是其本義,**一個瀏覽器窗口從打開到關閉這個期間**。

Session的目的則是,在一個客戶從打開瀏覽器到關閉瀏覽器這個期間內,發起的所有請求都可以被識別為同一個用戶。而實現的方式則是,在一個客戶打開瀏覽器開始訪問網站的時候,會生成一個SessionID,這個ID每次的訪問都會帶上,而服務器會識別這個SessionID並且將與這個SessionID有關的數據保存在服務器上。由此來實現客戶端的狀態識別。

Session與Cookie相反,Session是存儲在服務器上的數據,只由客戶端傳上來的SessionId來進行判定,所以相對於Cookie,Session的安全性更高。

一般SessionID會在瀏覽器被關閉時丟棄,或者服務器會驗證Session的活躍程度,例如30分鐘某一個SessionID都沒有活躍,那麽也會被識別為失效。

潭州課堂25班:Ph201805201 爬蟲基礎 第一課 (課堂筆記)