第一次正式接觸爬蟲 ---重要零散知識點的學習(one day)

1.爬蟲的概念

(1)爬蟲的概念:

網絡爬蟲也叫網絡蜘蛛,它特指一類自動批量下載網絡資源的程序,這是一個比較口語化的定義。
更加專業和全面對的定義是:網絡爬蟲是僞裝成客戶端與服務端進行數據交互的程序。

(2)爬蟲的應用:

  1. 數據採集
    大數據時代來臨,數據就是核心,數據就是生產力,越來越多的企業開始注重收集用戶數據,而爬蟲技術是收集數據的一種重要手段。
  2. 搜索引擎
    百度,谷歌等搜索引擎都是基於爬蟲技術。(PS:爬蟲界大佬!!!)
  3. 模擬操作
    爬蟲也被廣泛用於模擬用戶操作,測試機器人,灌水機器人等。

(3)爬蟲開發的重難點:

爬蟲難點主要分爲兩個方向:

  1. 數據的獲取(PS:自己人何苦爲難自己人嘞!)
    網絡公共資源都是爲用戶準備的,爲了避免被爬蟲採集,服務端會設置非常多的圖靈測試,阻止爬蟲的惡意爬取,也即是反爬措施。爬蟲開發工程師在開發爬蟲時,需要解決這些反爬措施。我們在開發爬蟲的過程中,有很大一部分的工作就是處理這些反爬措施。
  2. 採集的速度 (就像現在的你是不是一直在收藏,從未開始過)
    大數據時代,需要巨大的數據量,動輒千萬條的級別,甚至上億條。如果採集速度跟不上,耗時過長,那麼就達不到商業要求。一般我們會採取併發以及分佈式來解決速度上的問題。這也是爬蟲開發過程中的另外一個重心。

2.HTTP和HTTPS

(1)大多數商業應用採用的架構:

1.c/s 即 client server 客戶端 服務端

2.b/s 即 browser server 瀏覽器 服務端

3.m/s 即 moblie server 移動端 服務端

以上統稱爲客戶端與服務端
在這裏插入圖片描述網絡爬蟲是僞裝成客戶端與服務端進行數據交互的程序。那麼,客戶端和服務端該怎樣進行數據交互呢?就像我們中國人用中文交流,說的中國的語法,我們可以正常溝通。客戶端與服務端如果不統一一下,那不就亂套了,所以在網絡傳輸方面產生了衆多協議,HTTP就是其中一種。

(2)HTTP協議

目前互連網上90%的網絡傳輸都是基於http協議。

HTTP是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。

HTTP是一個基於TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。
注意:TCP/IP有個面向連接的特性!(意義:保證數據的完整性)
爲什麼要基於TCP/IP通信協議?這個特性有啥用?理解如下:
在這裏插入圖片描述三次握手建立連接:
客戶端說:嘿,服務端girl!我想和你建立連接。(打招呼)
服務端說:好的呢,我聽你的。
客戶端說:真好,那咱們開始數據交互吧(羞羞)。
.
.(幹羞羞的事ing,進行數據交互)
.
四次揮手斷開連接:
客戶端說:我已經和你交互完數據了,咱斷開連接吧!(打招呼)
服務端說:你確定斷開連接嘛?(不捨)
服務端又說:那你斷開連接吧!
客戶端說:好的,那我斷開連接了!

(3)HTTP請求流程:

我們日常用瀏覽器搜索東西,輸入的是URL,瀏覽器會將其自動轉換爲HTTP協議。

一次http請求的基本流程是,有客戶端向服務端發起一次請求(request), 而服務器在接收到以後返回給客戶端一個響應(response)。所以一次完整的http請求包含請求和響應兩部分。
在這裏插入圖片描述

(4)URL

發送http請求時,通過url對網絡資源進行定位。

URL(Uniform Resource Locator),中文叫統一資源定位符。是用來標識某一處資源的地址。也即是我們常說的網址。以下面這個URL爲例,介紹下普通URL的各部分組成:
協議+域名(端口默認80)+路徑+參數

注意:
1.http協議的端口號默認爲80可以不寫;https協議的端口號默認爲443可以不寫
2.域名通常是IP地址的映射,端口號通常是默認的就不寫。我們平常搜索時,比如進入百度:
https://www.baidu.com/,這裏的https協議的默認端口號爲443,就沒寫。

在這裏插入圖片描述

(5)HTTP請求格式

http請求
客戶端發送一個HTTP請求到服務器的請求消息包括以下部分:請求行,請求頭,空行和請求數據。

下圖給出請求報文的一般格式。
在這裏插入圖片描述注意:上圖中請求行的URL是指(4)URL中的路徑!
在這裏插入圖片描述

1.請求方法:

(1)

根據http標準,http請求可以使用多種請求方法。

1.0定義了三種請求方法:GET,POST和HEAD方法

1.1新增了五種請求法:OPTIONS,PUT,DELETE,TRACE和CONNECT方法。

(2)

常用方法 是 GET和POST。

  • GET
    1.主要是負責從服務器獲取數據
    2.URL中添加請求參數,顯示在地址欄
    3.請求字符串限制 1024個字節
    POST更加高效和方便。

  • POST
    1.主要負責向服務器提交數據
    2.沒有大小限制(但一般是2M)
    比’GET’傳遞數據量大,安全性高。

(3)

在這裏插入圖片描述

2.請求頭:

在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述

3.HTTP請求正文(請求數據)

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

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


來個承上啓下。既然現在請求格式已經OK了,即我們可以讓服務端聽懂我們說的話了;下面要做的就是讓我們能聽懂服務端給我們說的話了。

(6)HTTP響應格式

HTTP響應也由四個部分組成,分別是:狀態行(響應行)、消息報頭、空行和響應正文。

在這裏插入圖片描述下面給出響應報文的一般格式:
在這裏插入圖片描述

1.HTTP響應狀態碼:

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

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

在這裏插入圖片描述注意:重定向就相當於一箇中介轉接。

2.HTTP響應報頭:

在這裏插入圖片描述轉碼的格式


(7)總結:

1.HTTP流程總結:

在這裏插入圖片描述

2.HTTP協議的特點:

HTTP三點注意事項:

  • HTTP是無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。

  • HTTP是媒體獨立的:這意味着,只要客戶端和服務器知道如何處理的數據內容,任何類型的數據都可以通過HTTP發送。

  • HTTP是無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。
    注意:
    無狀態的意思是,比如你再一個網頁中輸入了賬號密碼登錄了QQ空間,但是由於HTTP是無狀態的,所以你再在QQ空間裏登錄QQ郵箱需要再輸入一次賬號和密碼,登錄的狀態是沒有被記憶的。但是可以利用會話技術解決。

3.HTTPS協議:

加強版的HTTP,公雞中的戰鬥機一枚!!!
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext Transfer Protocol Secure,超文本傳輸安全協議),是以安全爲目標的HTTP通道,簡單講是HTTP的安全版

http協議是基於tcp/ip協議的,而https是在http協議的基礎之上,再加了一層SSL/TLS協議,數據在傳輸過程中是加密的。

HTTPS協議的默認端口是443

3.會話技術

http是無狀態的,那服務端怎麼區分同一個用戶的連續請求呢,這就用到了會話技術:cookie和session。

(1)Cookie

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

Cookie 可以理解爲一個憑證
1.實際是由服務器發給客戶端的特殊信息,
2.這些信息以文本文件的方式存放在客戶端,
3.客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息。
服務器在接收到Cookie以後,會驗證Cookie的信息,以此來辨別用戶的身份。

(2)Session

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

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

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

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

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

(3)來個圖理解理解那麼枯燥的文字:

用戶首次登錄時:
會在服務器生成一個session表,裏面的key是hash生成的數據,value是一系列信息。
同時在客戶端本地生成一個文本文件cookie,這裏麪包含sessionid,而這個sessionid的值爲服務器中的hash形式的key。
在這裏插入圖片描述
用戶再次登錄時:
會自動攜帶sessionid及其值,這個值與服務器裏的hash形式的key比較,判斷用戶是否曾登錄成功,如果成功,則獲取用戶登錄的數據,然後返回給用戶請求的界面。
在這裏插入圖片描述

4.利用socket下載一張圖片

socket國外翻譯爲插座;同時,由於其具備了“套接”和“字”的概念,所以又稱爲套接字。
在這裏插入圖片描述

Socket是一種進程間通信機制,提供一種供應用程序
訪問通信協議的操作系統調用,使得網絡讀寫數據
和讀寫本地文件一樣容易;Socket是一序列的“指令” ;
已經具備了“套接”(建立網絡通訊或進程間通訊)和“字”(可交互的有序指令串)的概念。

在這裏插入圖片描述

(1)使用socket簡單建造一個服務端:

import socket
# 服務器對象
server = socket.socket()

# 1.綁定服務器
server.bind(("0.0.0.0",8800))   #0.0.0.0是允許所有人來訪問;8800是端口號

# 2.監聽
server.listen(5)

while True:
    # 3.等待連接
    conn,addr=server.accept()

    # 4.接收數據
    data=conn.recv(1024)
    print(data)

    response="HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8;\r\n\r\n<h1 style='color:black'>我很帥!<h1>"

    # 5.發送數據
    conn.send(response.encode())
    print("已經響應")

# 6.關閉
server.close()

在本地瀏覽器中輸入:127.0.0.1:8800即可訪問到此服務端:
在這裏插入圖片描述

(2)使用socket簡單建造一個客戶端:(爬取百度首頁整個界面)

import socket

# 建立服務器對象
client=socket.socket()

# 1.建立連接
client.connect(("www.baidu.com",80))

# 構造請求報文
data=b"GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n"

# 2.發送請求
client.send(data)
res=b""

# 3.接收數據
temp=client.recv(4096)
while temp:
    print("*"*50)
    res += temp
    temp = client.recv(4096)
    print(temp.decode())

# 4.斷開連接
client.close()

(3)使用socket來爬取一張漂亮景色的圖片:

據說搜狗是沒有設置反爬的,我們就來爬爬它。

1.首先,分析網頁:

在這裏插入圖片描述

而我們要爬取的圖片的URL就在頭信息裏的Request URL中。CV大法即可!

2.代碼:
#搜狗圖片 下載一張
import socket
import re
#搜狗圖片
img_url="https://i02piccdn.sogoucdn.com/a3ffebbb779e0baf"

'''  拓展:如何使用HTTPS請求
#HTTPS請求
import ssl
client = ssl.wrap_socket(socket.socket())   #ssl.wrap_socket 一個裝飾器
client.connect(('i02piccdn.sogoucdn.com',443))
'''

client = socket.socket()
# 創建連接              注意上面我們爬的是https協議的url,但是我們使用http也行的原因是自動進行了重定向
client.connect(("i02piccdn.sogoucdn.com",80))     #連接服務器,ip地址的映射可以定位到它的服務器

# 構造請求報文
data = "GET /a3ffebbb779e0baf HTTP/1.1\r\nHost:i02piccdn.sogoucdn.com\r\n\r\n"

# 發送數據
client.send(data.encode())   #報文要以字節碼的形式

# 接收數據
first_data = client.recv(1024)
print("first_data",first_data)

length = int(re.findall(b"Content-Length: (.*?)\r\n",first_data)[0]) #在列表裏,所以加0; 響應的也是字節碼形式,所以加b
print(length)   #內容長度

# 寫這句的原因是在雙\r\n後面可能有數據,也可能沒有,如果有就直接拿到了
# .*是匹配除了\r\n換行符之外的,後面加個re.S,則也可以匹配\r\n換行符,變成無敵的了!
image_data = re.findall(b"From Inner Cluster \r\n\r\n(.*?)",first_data,re.S)
if image_data:
    image_data = image_data[0]
else:
    image_data = b""

# 拼接拿到相應長度的數據
while True:
    temp = client.recv(1024)
    image_data += temp
    if len(image_data)>=length:
        break
# 4.斷開連接
client.close()

# 寫入文件
with open("girl.jpg","wb") as f:
    f.write(image_data)
3.實現效果:

在這裏插入圖片描述

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章