最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python抓取靜態(tài)網(wǎng)頁(yè)數(shù)據(jù)的完整指南

 更新時(shí)間:2025年11月19日 09:39:43   作者:embrace飛行日記  
靜態(tài)網(wǎng)頁(yè)是指網(wǎng)頁(yè)的內(nèi)容在服務(wù)器上被創(chuàng)建和存儲(chǔ)時(shí)就已經(jīng)完全確定好了,本文將和大家詳細(xì)講講如何使用Python抓取靜態(tài)網(wǎng)頁(yè)數(shù)據(jù),感興趣的小伙伴可以了解下

一.什么是靜態(tài)網(wǎng)頁(yè)

1.靜態(tài)網(wǎng)頁(yè)的含義

靜態(tài)網(wǎng)頁(yè)是指網(wǎng)頁(yè)的內(nèi)容在服務(wù)器上被創(chuàng)建和存儲(chǔ)時(shí)就已經(jīng)完全確定好了。當(dāng)用戶通過(guò)瀏覽器請(qǐng)求這個(gè)網(wǎng)頁(yè)時(shí),服務(wù)器會(huì)原封不動(dòng)地將這個(gè)預(yù)先制作好的文件(通常是.html、.css、.js文件),發(fā)送給用戶的瀏覽器。網(wǎng)頁(yè)的內(nèi)容不會(huì)因用戶的不同,時(shí)間的變化或用戶的交互而改變。

可以想象成一本書(shū)的某一頁(yè),或者一張打印出來(lái)的宣傳單頁(yè):它的內(nèi)容在印刷完成的那一刻就已經(jīng)固定了。

2.靜態(tài)網(wǎng)頁(yè)的特點(diǎn)

1.內(nèi)容固定不變

網(wǎng)頁(yè)上的所有文字、圖片、布局和鏈接都是開(kāi)發(fā)人員在編寫(xiě)代碼時(shí)就已經(jīng)確定好的,除非開(kāi)發(fā)人員手動(dòng)修改源代碼并且重新上傳到服務(wù)器,否則任何用戶在任何時(shí)間、任何地點(diǎn)看到的網(wǎng)頁(yè)內(nèi)容都是一樣的

2.服務(wù)器處理簡(jiǎn)單

服務(wù)器不需要處理任何額外的程序或查詢數(shù)據(jù)庫(kù),它的任務(wù)僅僅是找到用戶查詢的文件,然后把它發(fā)送出去。這就像從一個(gè)文件柜里取出一個(gè)已經(jīng)歸檔的文件。

3.加載速度快

因?yàn)榉?wù)器不需要進(jìn)行任何動(dòng)態(tài)數(shù)據(jù)處理,所以相應(yīng)速度非常快。能極大提升用戶體驗(yàn)和搜索引擎排名

4.開(kāi)發(fā)成本低,易于部署

靜態(tài)網(wǎng)頁(yè)通常只由HTML、CSS、JavaScript這三種前端技術(shù)組成,開(kāi)發(fā)簡(jiǎn)單,對(duì)服務(wù)器環(huán)境要求低,部署也非常方便

5.安全性高

由于沒(méi)有與數(shù)據(jù)庫(kù)的交互和執(zhí)行服務(wù)器端腳本(如PHP、Python),它受黑客攻擊的入口點(diǎn)更少,因此比動(dòng)態(tài) 網(wǎng)頁(yè)更安全

3.靜態(tài)網(wǎng)頁(yè)的技術(shù)構(gòu)成

  • HTML:負(fù)責(zé)網(wǎng)頁(yè)的內(nèi)容和結(jié)構(gòu),比如標(biāo)題、段落、圖片、鏈接等
  • CSS:負(fù)責(zé)網(wǎng)頁(yè)的樣式和布局,比如顏色、字體、間距、相應(yīng)式設(shè)計(jì)等
  • JavaScript:負(fù)責(zé)網(wǎng)頁(yè)的交互行為,比如下拉表單、圖片輪播、表單驗(yàn)證等

重要提示:一個(gè)網(wǎng)頁(yè)即使包含了復(fù)雜的JavaScript動(dòng)畫(huà)和交互,只要它的核心內(nèi)容(如文章、產(chǎn)品、公司介紹)是預(yù)先寫(xiě)死在HTML里面的,它仍然屬于靜態(tài)網(wǎng)頁(yè)

4.靜態(tài)網(wǎng)頁(yè) vs. 動(dòng)態(tài) 網(wǎng)頁(yè)

為了更好地理解,我們將其與動(dòng)態(tài) 網(wǎng)頁(yè)進(jìn)行對(duì)比:

特性靜態(tài)網(wǎng)頁(yè)動(dòng)態(tài) 網(wǎng)頁(yè)
內(nèi)容來(lái)源預(yù)先編寫(xiě)好的HTML文件服務(wù)器端腳本(PHP, Python, Node.js等)實(shí)時(shí)從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源獲取數(shù)據(jù)并生成HTML
內(nèi)容變化手動(dòng)更新源代碼根據(jù)用戶、時(shí)間、數(shù)據(jù)庫(kù)狀態(tài)等自動(dòng)變化
服務(wù)器負(fù)載低(主要是文件傳輸)高(需要執(zhí)行腳本和數(shù)據(jù)庫(kù)查詢)
開(kāi)發(fā)復(fù)雜度
典型例子公司官網(wǎng)、個(gè)人博客、產(chǎn)品介紹頁(yè)、活動(dòng)宣傳頁(yè)社交媒體(如微博、微信)、電商網(wǎng)站(如淘寶)、在線郵箱(如Gmail)

5.現(xiàn)代靜態(tài)網(wǎng)站的演進(jìn)

傳統(tǒng)的靜態(tài)網(wǎng)頁(yè)概念在今天有了一些新的發(fā)展,特別是 Jamstack 架構(gòu)的流行。

Jamstack 的核心思想是:

  • 預(yù)渲染:在部署之前,使用靜態(tài)站點(diǎn)生成器(如 Gatsby, Next.js, Hugo, Jekyll)將網(wǎng)站的所有頁(yè)面提前生成為靜態(tài)文件。
  • 解耦架構(gòu):通過(guò) APIs 和 微服務(wù) 來(lái)處理動(dòng)態(tài)功能。

例如:一個(gè)新聞網(wǎng)站。

傳統(tǒng)靜態(tài):每篇新文章都需要手動(dòng)寫(xiě)一個(gè)HTML文件。

現(xiàn)代Jamstack

  • 編輯在內(nèi)容管理系統(tǒng)(如WordPress + Headless插件,或Contentful)中寫(xiě)好文章。
  • 當(dāng)文章發(fā)布時(shí),會(huì)觸發(fā)一個(gè)構(gòu)建流程。
  • 靜態(tài)站點(diǎn)生成器(如Gatsby)會(huì)從CMS的API獲取這篇新文章的內(nèi)容,自動(dòng)生成一個(gè)新的靜態(tài)HTML頁(yè)面,并更新網(wǎng)站列表頁(yè)。
  • 最后將整個(gè)更新后的靜態(tài)網(wǎng)站部署到服務(wù)器。

這樣,它既保留了靜態(tài)網(wǎng)站快速、安全的優(yōu)點(diǎn),又具備了易于內(nèi)容更新的動(dòng)態(tài)能力。

二.抓取靜態(tài)網(wǎng)頁(yè)的技術(shù)

靜態(tài)網(wǎng)頁(yè)是HTML格式的網(wǎng)頁(yè),這種網(wǎng)頁(yè)在瀏覽器中呈現(xiàn)的內(nèi)容都會(huì)體現(xiàn)在源代碼中。如果我們要抓取靜態(tài)網(wǎng)頁(yè)的數(shù)據(jù),只需要獲得網(wǎng)頁(yè)的源代碼即可。

網(wǎng)絡(luò)爬蟲(chóng)抓取靜態(tài)網(wǎng)頁(yè)數(shù)據(jù)的過(guò)程是獲得網(wǎng)頁(yè)原代碼的過(guò)程,這個(gè)過(guò)程也就是模擬用戶通過(guò)瀏覽器訪問(wèn)網(wǎng)頁(yè)的過(guò)程,包括向Web服務(wù)器發(fā)送HTTP請(qǐng)求、服務(wù)器對(duì)HTTP請(qǐng)求作出相應(yīng)并返回網(wǎng)頁(yè)源代碼

ulrlib、urllib3、requests是Python提供的可以抓取靜態(tài)網(wǎng)頁(yè)的庫(kù)

1.urllib

urllib是Python最早的內(nèi)置的HTTP客戶端庫(kù),涵蓋了基礎(chǔ)的網(wǎng)絡(luò)請(qǐng)求功能

它主要包含了4個(gè)用于處理URL的模塊:urllib.error模塊、urllib.error模塊、urllib.parse模塊、urllib.robotparser模塊

其中urllib.requests模塊封裝了構(gòu)造和發(fā)送網(wǎng)絡(luò)請(qǐng)求的功能

urllib.error模塊封裝了發(fā)送請(qǐng)求時(shí)出現(xiàn)的網(wǎng)絡(luò)異常

urllib.parse模塊封裝了解析網(wǎng)頁(yè)數(shù)據(jù)的功能

urllib.robotparser模塊封裝解析robots.txt文件的功能

2.urllib3

它主要服務(wù)于升級(jí)的HTTP1.1標(biāo)準(zhǔn),增加了一些urllib庫(kù)中缺少了特性,如線程安全、連接池、客戶端TLS/SSL驗(yàn)證、壓縮編碼

3.requests

基于urllib3編寫(xiě)的庫(kù),該庫(kù)自稱HTTP for Humans,專門(mén)為人類設(shè)計(jì)的HTTP庫(kù)

相比urllib,requests庫(kù)會(huì)在請(qǐng)求網(wǎng)頁(yè)數(shù)據(jù)后重復(fù)使用Socket套接字,并沒(méi)有與服務(wù)器斷開(kāi),而urllib庫(kù)會(huì)在請(qǐng)求網(wǎng)頁(yè)數(shù)據(jù)后斷開(kāi)與服務(wù)器的鏈接

三.發(fā)送基本請(qǐng)求

GET和POST是HTTP協(xié)議中最常用的兩種請(qǐng)求方法,它們?cè)谠O(shè)計(jì)理念和使用場(chǎng)景上有本質(zhì)區(qū)別。

GET和POST請(qǐng)求核心區(qū)別總結(jié)

特性GETPOST
語(yǔ)義獲取數(shù)據(jù)提交數(shù)據(jù)
參數(shù)位置URL查詢字符串請(qǐng)求體
參數(shù)可見(jiàn)性明文顯示在URL中隱藏在請(qǐng)求體中
數(shù)據(jù)長(zhǎng)度有限制(瀏覽器不同)理論上無(wú)限制
安全性較低(參數(shù)在URL中)相對(duì)較高
緩存可被緩存通常不被緩存
冪等性冪等(多次請(qǐng)求結(jié)果相同)非冪等
書(shū)簽可收藏為書(shū)簽不可收藏

1.發(fā)送GET請(qǐng)求

不攜帶URL參數(shù)的GET請(qǐng)求

import requests
base_url = 'https://www.baidu.com/'
response = requests.get(base_url)
print("響應(yīng)碼為:",response.status_code) #響應(yīng)碼為: 200

上面的代碼中,GET請(qǐng)求中的URL沒(méi)有攜帶參數(shù),

url參數(shù)是必需的

params參數(shù)(param英文意思就是參數(shù),paramter:界限,范圍,參數(shù))

發(fā)送攜帶參數(shù)的URL的GET請(qǐng)求

params參數(shù)就是用于查詢字符串的,它可以是一個(gè)字典,一個(gè)包含鍵值對(duì)的列表,或者一個(gè)字節(jié)字符串

import requests
base_url = 'https://www.baidu.com/'
param = 'wd=python'
full_url = base_url + '?' + param
# print(full_url) #https://www.baidu.com/?wd=python
response = requests.get(full_url)
print("響應(yīng)碼為:",response.status_code) # 響應(yīng)碼為: 200
import requests
base_url = 'https://www.baidu.com/'
wd_params = {'wd':'python'}
response = requests.get(base_url, params=wd_params)
print(response.status_code) #200

params的參數(shù)值為字典這種使用最常用

2.發(fā)送POST請(qǐng)求

如果網(wǎng)頁(yè)上form表單的method屬性的值為post,那么當(dāng)用戶提交表單時(shí),瀏覽器會(huì)用POST方法提交表單,并將各個(gè)表單元素及數(shù)據(jù)作為HTTP請(qǐng)求信息中的請(qǐng)求數(shù)據(jù)發(fā)送給服務(wù)器

POST請(qǐng)求方法用于發(fā)送HTTP POST請(qǐng)求,它比GET請(qǐng)求更安全,因?yàn)閰?shù)不會(huì)出現(xiàn)在URL中,而是放在請(qǐng)求體中,POST請(qǐng)求通常用于提交表單、上傳文件、調(diào)用API等

基本使用方法:

response = requests.post(url, data=None, json=None, **kwargs)

主要參數(shù):

  • url: 請(qǐng)求的目標(biāo)URL(必需)
  • data: 字典、元組列表、字節(jié)或文件對(duì)象,用于作為表單數(shù)據(jù)發(fā)送
  • json: 字典,用于作為JSON數(shù)據(jù)發(fā)送,會(huì)自動(dòng)設(shè)置Content-Type為application/json
  • **kwargs: 其他可選參數(shù),如headers、cookies、auth、timeout等,與requests.get()相同
import requests
base_url = "https://www.gushiwen.cn/"
data = {
    'username':'user_name',
    'password':12345678,
}
response = requests.post(url=base_url, data=data)
print(response.status_code) # 200

爬取并保存古詩(shī)文網(wǎng)中蘇軾的HTML數(shù)據(jù):

import requests
base_url = 'https://www.gushiwen.cn/'
data = {
    'wd':'蘇軾'
}
# response = requests.post(base_url, data=data)
response = requests.get(base_url, params=data)
print(response.status_code)
with open("古詩(shī)文-蘇軾.html", 'wb') as file:
    file.write(response.content)
print(response.url)

這段代碼可以正常地運(yùn)行,正常地保存了.html文件,正常輸出了url的最終形式:https://www.gushiwen.cn/?wd=%E8%8B%8F%E8%BD%BC

但是當(dāng)我們用這個(gè)輸出的url去瀏覽器中訪問(wèn)時(shí),發(fā)現(xiàn)還是首頁(yè)的頁(yè)面,并不是查找蘇軾后的有關(guān)蘇軾古詩(shī)文的頁(yè)面

原因在于:使用的是主頁(yè) URL https://www.gushiwen.cn/,而不是搜索頁(yè)面的 URL

古詩(shī)文網(wǎng)的搜索功能通常有專門(mén)的搜索頁(yè)面

我們需要查看古詩(shī)文網(wǎng)中搜索表單的實(shí)際參數(shù)名

注:搜索功能一般是GET方法,不是POST方法哦

我們通??梢酝ㄟ^(guò)以下方式找到正確的搜索URL和請(qǐng)求方式:

  • 瀏覽器的開(kāi)發(fā)者工具(按F12打開(kāi)),特別是網(wǎng)絡(luò)(Network)選項(xiàng)卡。
  • 觀察網(wǎng)頁(yè)的搜索表單(如果有的話)的HTML結(jié)構(gòu)

步驟1:打開(kāi)古詩(shī)文網(wǎng),找到搜索框。

步驟2:打開(kāi)瀏覽器的開(kāi)發(fā)者工具,切換到網(wǎng)絡(luò)(Network)選項(xiàng)卡,并清空當(dāng)前記錄。

步驟3:在搜索框中輸入“蘇軾”,然后執(zhí)行搜索。

步驟4:在開(kāi)發(fā)者工具的網(wǎng)絡(luò)選項(xiàng)卡中,會(huì)看到瀏覽器發(fā)送的請(qǐng)求,找到第一個(gè)搜索結(jié)果的請(qǐng)求,點(diǎn)擊查看其詳細(xì)信息。

主文檔請(qǐng)求 - 這是最重要的

  • 類型通常是 "document" 或 "xhr"(或者fatch類型的文檔,這些一般都是接口數(shù)據(jù))
  • 名稱通常包含 "search"、"so" 等關(guān)鍵詞
  • 這是實(shí)際返回搜索結(jié)果HTML頁(yè)面的請(qǐng)求

如何識(shí)別

  • 清空Network面板:在點(diǎn)擊搜索按鈕前,先點(diǎn)擊Network面板上的 ?? 清除按鈕
  • 執(zhí)行搜索:在網(wǎng)站上輸入"蘇軾"并點(diǎn)擊搜索
  • 觀察新出現(xiàn)的請(qǐng)求:你會(huì)看到一堆新的請(qǐng)求出現(xiàn)

重點(diǎn)關(guān)注

  • Name列排序,找包含 "search" 的請(qǐng)求
  • Type列找 "document" 類型的請(qǐng)求
  • Size列找較大的請(qǐng)求(通常主頁(yè)面比較大)

我們?cè)陂_(kāi)發(fā)者工具的網(wǎng)絡(luò)選項(xiàng)卡中發(fā)現(xiàn)了第一個(gè)文檔,后綴名為.document

該文檔中包含的url信息為:https://www.gushiwen.cn/search.aspx?value=%E8%8B%8F%E8%BD%BC

url組成部分分解

  • https:// - 協(xié)議類型(安全超文本傳輸協(xié)議)
  • www.gushiwen.cn - 域名(古詩(shī)文網(wǎng))
  • /search.aspx - 服務(wù)器上的搜索處理頁(yè)面
  • ?value= - 查詢參數(shù)開(kāi)始,參數(shù)名為value
  • %E8%8B%8F%E8%BD%BC - "蘇軾"的URL編碼形式

關(guān)于URL編碼

URL編碼(也叫百分號(hào)編碼)是將特殊字符轉(zhuǎn)換為%后跟兩位十六進(jìn)制數(shù)的形式。

  • %E8%8B%8F = "蘇"
  • %E8%BD%BC = "軾"

可以在python中驗(yàn)證:

from urllib.parse import quote, unquote

# 編碼
encoded = quote('蘇軾')
print(f"編碼后: {encoded}")  # 輸出: %E8%8B%8F%E8%BD%BC

# 解碼
decoded = unquote('%E8%8B%8F%E8%BD%BC')
print(f"解碼后: {decoded}")  # 輸出: 蘇軾

判斷正確URL的方法

時(shí)間順序法

  • 在點(diǎn)擊搜索按鈕之前,先清空Network面板
  • 點(diǎn)擊搜索后,第一個(gè)出現(xiàn)的文檔請(qǐng)求很可能就是搜索請(qǐng)求
  • 因?yàn)樗阉鲃?dòng)作會(huì)觸發(fā)頁(yè)面跳轉(zhuǎn),這個(gè)跳轉(zhuǎn)的請(qǐng)求應(yīng)該是最先發(fā)起的

URL特征法

正確的搜索URL通常有這些特征:

  • 包含 searchso、queryfind 等關(guān)鍵詞
  • 參數(shù)中包含你的搜索詞(編碼后的)
  • 通常是 .aspx、.php、/search/ 等動(dòng)態(tài)頁(yè)面

大小和類型判斷

  • 搜索結(jié)果的HTML頁(yè)面通常比較大(幾十KB到幾百KB)
  • 靜態(tài)資源(CSS、JS、圖片)通常較小或有特定類型

Headers信息驗(yàn)證

在開(kāi)發(fā)者工具中,點(diǎn)擊候選請(qǐng)求,查看:

  • Response Headers 中的 Content-Type 應(yīng)該是 text/html
  • Request Headers 中可以看到完整的請(qǐng)求信息

正確的實(shí)現(xiàn)代碼:

import requests
base_url = 'https://www.gushiwen.cn/search.aspx?'
params = {
    'value':'蘇軾',
}
response = requests.get(url=base_url, params=params)
response.raise_for_status()
print(response.url)
with open("古詩(shī)文-蘇軾.html", 'wb') as f:
    f.write(response.content)

輸出的url:https://www.gushiwen.cn/search.aspx?value=%E8%8B%8F%E8%BD%BC

3.處理復(fù)雜的請(qǐng)求

比如定制請(qǐng)求頭,網(wǎng)絡(luò)爬蟲(chóng)在發(fā)送請(qǐng)求抓取部分網(wǎng)頁(yè)內(nèi)容(如知乎首頁(yè))時(shí),可能會(huì)遇到服務(wù)器返回403錯(cuò)誤,即服務(wù)器有能力處理請(qǐng)求,但是拒絕處理該客戶端發(fā)送的請(qǐng)求。之所以出現(xiàn)服務(wù)器拒絕訪問(wèn)的問(wèn)題,是因?yàn)檫@些網(wǎng)頁(yè)為防止網(wǎng)絡(luò)爬蟲(chóng)惡意抓取網(wǎng)頁(yè)信息加入防爬蟲(chóng)措施。

它們通過(guò)檢查該請(qǐng)求頭,判定發(fā)送的請(qǐng)求不是客戶端,而可能是一個(gè)網(wǎng)絡(luò)爬蟲(chóng)

所以為了解決這個(gè)問(wèn)題,需要為網(wǎng)絡(luò)爬蟲(chóng)的請(qǐng)求定制一個(gè)請(qǐng)求頭,使得該請(qǐng)求偽裝成一個(gè)由瀏覽器發(fā)送的請(qǐng)求

在請(qǐng)求頭中添加User-Agent(用戶代理)

在請(qǐng)求中添加Cookie值{
        設(shè)置Cookie有兩種方式{
        1.將含有Cookie的信息的請(qǐng)求頭傳入請(qǐng)求函數(shù)的headers參數(shù)中(字典形式)
        2.將Cookie信息的請(qǐng)求頭傳輸cookies參數(shù)中,cookies參數(shù)接受一個(gè)RequestsCookieJar類的對(duì)象
        }
}

使用session保持會(huì)話

SSL證書(shū)驗(yàn)證

設(shè)置代理服務(wù)器

四.對(duì)Cookie、Session、Token的一些理解

當(dāng)用戶首次登入一個(gè)網(wǎng)站時(shí),網(wǎng)站往往需要用戶輸入用戶名稱和用戶密碼,并給出自動(dòng)登入選項(xiàng)供用戶勾選。用戶如果勾選了自動(dòng)登入選項(xiàng),那么在下一次訪問(wèn)該網(wǎng)站時(shí),不用輸入用戶名和密碼就能自動(dòng)登入。這是因?yàn)榈谝淮蔚侨霑r(shí)服務(wù)器發(fā)送了包含登入憑證的Cookie到用戶硬盤(pán)上,第二次登入時(shí)瀏覽器發(fā)送了Cookie,服務(wù)器驗(yàn)證了Cookie后就識(shí)別了用戶的身份,用戶便無(wú)需用戶名和密碼就可以登入該網(wǎng)站

Cookie(有時(shí)候也稱Cookies)是指某些網(wǎng)站為了辨別用戶身份、進(jìn)行會(huì)話跟蹤而暫時(shí)存儲(chǔ)在客戶端的一段文本數(shù)據(jù)(通常經(jīng)過(guò)加密)

我們可以打開(kāi)瀏覽器來(lái)看一下我們的瀏覽器保存了哪些Cookie:

打開(kāi)瀏覽器的設(shè)置  →   點(diǎn)擊“隱私、搜索和服務(wù)”   →    在彈出來(lái)的界面中點(diǎn)擊Cookie

這相當(dāng)于說(shuō)把用戶名和密碼發(fā)在Cookie里是不夠安全的,電腦被黑,存儲(chǔ)在瀏覽器中的Cookie信息就會(huì)被盜取

瀏覽器訪問(wèn)服務(wù)器就是會(huì)話的開(kāi)始,但是會(huì)話的結(jié)束就相對(duì)來(lái)說(shuō)模糊一點(diǎn),當(dāng)你不小心關(guān)閉了這個(gè)網(wǎng)頁(yè),算不算會(huì)話的結(jié)束?
因此不同的網(wǎng)站會(huì)給用戶的會(huì)話設(shè)置了時(shí)間和一個(gè)唯一的ID,這個(gè)ID也就是Session ID,時(shí)間是會(huì)話的時(shí)間。這些數(shù)據(jù)由服務(wù)器設(shè)置,一般都保存在數(shù)據(jù)庫(kù)里面

Cookie

是什么:Cookie是一小段數(shù)據(jù)(最大通常為4KB),由服務(wù)器通過(guò)HTTP響應(yīng)頭的 Set-Cookie 字段發(fā)送給客戶端(通常是瀏覽器)。瀏覽器會(huì)將其保存起來(lái),并在后續(xù)對(duì)同一域名的請(qǐng)求中,自動(dòng)通過(guò)HTTP請(qǐng)求頭的 Cookie 字段將其攜帶回服務(wù)器。

核心特點(diǎn)

  • 存儲(chǔ)在客戶端:數(shù)據(jù)保存在瀏覽器端。
  • 自動(dòng)攜帶:瀏覽器會(huì)自動(dòng)在符合條件的請(qǐng)求中附帶上Cookie。
  • 有域和路徑限制:只能被創(chuàng)建它的域名或路徑訪問(wèn),遵循同源策略。
  • 可設(shè)置過(guò)期時(shí)間:可以是會(huì)話級(jí)(瀏覽器關(guān)閉即失效),也可以是持久性的(直到設(shè)定的過(guò)期時(shí)間)。

主要用途

  • 會(huì)話狀態(tài)管理(如用戶登錄狀態(tài)、購(gòu)物車)
  • 個(gè)性化設(shè)置(如主題、語(yǔ)言偏好)
  • 瀏覽器行為跟蹤(如用戶行為分析)

Session

是什么:Session代表的是一次用戶與服務(wù)器的交互會(huì)話。它是一種在服務(wù)器端保存用戶狀態(tài)和信息的機(jī)制。每個(gè)Session都有一個(gè)唯一的標(biāo)識(shí)符,稱為 Session ID。

核心特點(diǎn)

  • 存儲(chǔ)在服務(wù)器端:用戶的真實(shí)數(shù)據(jù)(如用戶ID、用戶名、權(quán)限等)保存在服務(wù)器的內(nèi)存、文件或數(shù)據(jù)庫(kù)中。
  • 依賴Cookie(或URL重寫(xiě)):服務(wù)器為了區(qū)分不同的客戶端,會(huì)將 Session ID 通過(guò)Cookie(Set-Cookie: session_id=abc123...)發(fā)送給客戶端??蛻舳撕罄m(xù)請(qǐng)求時(shí)攜帶這個(gè) Session ID,服務(wù)器根據(jù)這個(gè)ID找到對(duì)應(yīng)的Session數(shù)據(jù)。
  • 更安全:因?yàn)槊舾袛?shù)據(jù)都存在服務(wù)器,客戶端只有一個(gè)無(wú)意義的ID。

工作流程簡(jiǎn)述

  • 用戶登錄,服務(wù)器驗(yàn)證通過(guò)后,創(chuàng)建Session,并生成唯一 Session ID
  • 服務(wù)器通過(guò)響應(yīng)頭 Set-Cookie 將 Session ID 發(fā)給瀏覽器。
  • 瀏覽器保存這個(gè)Cookie,之后每次請(qǐng)求都會(huì)帶上這個(gè) Session ID。
  • 服務(wù)器收到請(qǐng)求,解析出 Session ID,并從存儲(chǔ)中查找對(duì)應(yīng)的Session數(shù)據(jù),從而得知用戶身份。

Token

是什么:Token是一種身份憑證,是服務(wù)器生成的一串字符串,其中包含了用戶信息和簽名。最常見(jiàn)的Token是 JWT(JSON Web Token)。

核心特點(diǎn)

  • 自包含:Token本身(以JWT為例)就包含了所有需要的信息,如用戶ID、過(guò)期時(shí)間等。服務(wù)器無(wú)需在服務(wù)端存儲(chǔ)會(huì)話狀態(tài)。
  • 存儲(chǔ)在客戶端:由客戶端保存,通??梢源鎯?chǔ)在Local Storage、Session Storage或Cookie中。
  • 需要手動(dòng)攜帶:客戶端需要在每次請(qǐng)求時(shí),手動(dòng)地將其添加到請(qǐng)求頭中(通常是 Authorization: Bearer <token>),瀏覽器不會(huì)像Cookie一樣自動(dòng)發(fā)送。
  • 無(wú)狀態(tài):服務(wù)器驗(yàn)證Token的簽名即可確認(rèn)其有效性,不需要在服務(wù)器端存儲(chǔ)任何會(huì)話信息。這使得服務(wù)器擴(kuò)展非常容易。

工作流程簡(jiǎn)述(以JWT為例)

  • 用戶登錄,服務(wù)器驗(yàn)證通過(guò)后,生成一個(gè)JWT(包含用戶信息和簽名),將其返回給客戶端。
  • 客戶端保存這個(gè)JWT(例如在Local Storage中)。
  • 客戶端后續(xù)請(qǐng)求API時(shí),在HTTP請(qǐng)求頭的 Authorization 字段中攜帶這個(gè)JWT。
  • 服務(wù)器收到請(qǐng)求,驗(yàn)證JWT的簽名是否有效、是否過(guò)期。如果有效,就直接使用Token中包含的用戶信息進(jìn)行后續(xù)處理。

三者的聯(lián)系

Cookie 和 Session 是“黃金搭檔”:在傳統(tǒng)的Session認(rèn)證方案中,Cookie是Session ID的載體。Session機(jī)制解決了HTTP協(xié)議無(wú)狀態(tài)的問(wèn)題,而Cookie解決了Session ID的傳遞和存儲(chǔ)問(wèn)題。它們是相輔相成、密不可分的一對(duì)。

Token 可以作為 Cookie 的內(nèi)容:Token也可以選擇存儲(chǔ)在Cookie中,由瀏覽器自動(dòng)管理。這種方式結(jié)合了Cookie的自動(dòng)攜帶和Token的無(wú)狀態(tài)優(yōu)點(diǎn),但需要注意防范CSRF攻擊。

共同目標(biāo):三者的終極目標(biāo)都是為了在無(wú)狀態(tài)的HTTP協(xié)議之上,實(shí)現(xiàn)有狀態(tài)的用戶身份認(rèn)證和會(huì)話管理

核心區(qū)別(重點(diǎn))

特性CookieSessionToken (以JWT為例)
存儲(chǔ)位置客戶端(瀏覽器)服務(wù)器端(內(nèi)存、DB、Redis)客戶端(LocalStorage, Cookie等)
安全性較低,易被XSS和CSRF攻擊較高,敏感信息在服務(wù)器較高,但需防XSS。簽名防篡改
擴(kuò)展性-差,服務(wù)器集群間同步Session復(fù)雜,無(wú)狀態(tài),天然支持分布式
跨域支持受同源策略限制,需額外配置CORS受同源策略限制容易,可在請(qǐng)求頭中攜帶,支持CORS
傳輸方式瀏覽器自動(dòng)通過(guò)Cookie請(qǐng)求頭攜帶通過(guò)Cookie攜帶其ID手動(dòng)通過(guò)Authorization等請(qǐng)求頭攜帶
數(shù)據(jù)容量小(約4KB)大(受服務(wù)器資源限制)中等(不宜過(guò)大,影響傳輸效率)
服務(wù)器壓力無(wú)大,需要存儲(chǔ)所有用戶的會(huì)話數(shù)據(jù)小,只需驗(yàn)證簽名,無(wú)需存儲(chǔ)

為了幫助你更好地理解,我們可以用一個(gè)形象的比喻:

Cookie 就像 “會(huì)員卡”。

你(瀏覽器)去健身房(服務(wù)器),前臺(tái)(服務(wù)器)給你一張印有卡號(hào)(Session ID)的會(huì)員卡(Cookie)。你下次來(lái),直接出示卡(自動(dòng)攜帶Cookie),前臺(tái)通過(guò)卡號(hào)查到你的檔案(Session)。

Session 就像 “健身房前臺(tái)的會(huì)員檔案柜”。

里面存著所有會(huì)員的詳細(xì)資料(用戶數(shù)據(jù))??ㄌ?hào)(Session ID)是打開(kāi)對(duì)應(yīng)檔案抽屜的鑰匙。

Token (JWT) 就像 “一張加密的防偽門(mén)票”

你第一次驗(yàn)票進(jìn)場(chǎng)后,檢票處(服務(wù)器)給你一張?zhí)厥獠馁|(zhì)的門(mén)票(Token),上面用特殊工藝印著你的身份信息和防偽碼(簽名)。你去看每個(gè)場(chǎng)館(訪問(wèn)每個(gè)API)時(shí),都需要主動(dòng)出示這張票(手動(dòng)攜帶Token),檢票處用特定燈光(驗(yàn)證算法)一照,就能辨別真?zhèn)?,無(wú)需再回總臺(tái)查名單。

如何選擇?

  • 傳統(tǒng)Web應(yīng)用(有服務(wù)端模板渲染,如JSP, PHP):使用 Cookie + Session 非常自然和方便。
  • 前后端分離應(yīng)用(如React/Vue + Node.js/Java API)、移動(dòng)端APP或需要跨域認(rèn)證的場(chǎng)景:使用 Token(尤其是JWT) 是更現(xiàn)代、更合適的選擇,因?yàn)樗鼰o(wú)狀態(tài)、擴(kuò)展性好

五.用戶的真實(shí)賬號(hào)和密碼被存在了哪里

我們通常不會(huì)將用戶的真實(shí)密碼和賬號(hào)保存在Cookie或Session中。這樣做會(huì)帶來(lái)嚴(yán)重的安全風(fēng)險(xiǎn)。下面分別說(shuō)明:

Cookie:如果將用戶的賬號(hào)和密碼直接保存在Cookie中,那么這些敏感信息就會(huì)以明文形式存儲(chǔ)在用戶的瀏覽器中,并且每次請(qǐng)求都會(huì)自動(dòng)發(fā)送給服務(wù)器。這極易導(dǎo)致信息泄露,例如:

  • 如果Cookie被竊?。ㄍㄟ^(guò)XSS攻擊),攻擊者就能拿到用戶的賬號(hào)和密碼。
  • 即使加密存儲(chǔ),也不安全,因?yàn)槊荑€同樣需要存儲(chǔ)在客戶端,且加密可能被破解。

Session:在Session中,我們通常也不會(huì)保存用戶的真實(shí)密碼。Session中存儲(chǔ)的是用戶登錄后的狀態(tài)信息,例如用戶ID、用戶名、登錄狀態(tài)等。用戶的密碼在登錄驗(yàn)證通過(guò)后,就不應(yīng)該再被保留在Session中。

那么,正確的做法是怎樣的呢?

正確的認(rèn)證流程

  • 用戶登錄:用戶提交賬號(hào)和密碼。
  • 服務(wù)器驗(yàn)證:服務(wù)器在數(shù)據(jù)庫(kù)中查找該賬號(hào),并驗(yàn)證密碼(通常數(shù)據(jù)庫(kù)中的密碼是經(jīng)過(guò)哈希加密的,不會(huì)存儲(chǔ)明文密碼)。
  • 創(chuàng)建Session:驗(yàn)證通過(guò)后,服務(wù)器創(chuàng)建一個(gè)Session,在Session中存儲(chǔ)一些不敏感的用戶信息(如用戶ID、用戶名等)和登錄狀態(tài)。
  • 設(shè)置Cookie:服務(wù)器將Session ID通過(guò)Cookie返回給瀏覽器,瀏覽器后續(xù)請(qǐng)求會(huì)攜帶這個(gè)Session ID。
  • 后續(xù)請(qǐng)求:服務(wù)器通過(guò)Session ID找到對(duì)應(yīng)的Session,從而知道是哪個(gè)用戶。

另外,使用Token(如JWT)的方式:

  • 用戶登錄:用戶提交賬號(hào)和密碼。
  • 服務(wù)器驗(yàn)證:驗(yàn)證通過(guò)后,服務(wù)器生成一個(gè)Token(如JWT),Token中包含一些用戶信息(如用戶ID)和過(guò)期時(shí)間,并用服務(wù)器密鑰簽名。
  • 返回Token:服務(wù)器將Token返回給客戶端,客戶端保存(通常放在localStorage或Cookie中)。
  • 后續(xù)請(qǐng)求:客戶端在請(qǐng)求頭中攜帶Token,服務(wù)器驗(yàn)證Token的簽名和有效性,從而識(shí)別用戶。

在Token方式中,密碼同樣不會(huì)存儲(chǔ)在Token中,Token中只包含必要的信息(如用戶ID)和簽名。

總結(jié)

  • 絕對(duì)不要將用戶的真實(shí)密碼存儲(chǔ)在Cookie或Session中。
  • 在Session中只存儲(chǔ)必要的用戶標(biāo)識(shí)和狀態(tài),而不是敏感信息。
  • 在認(rèn)證過(guò)程中,密碼應(yīng)該通過(guò)安全通道(如HTTPS)傳輸,并且在服務(wù)器端與存儲(chǔ)的哈希值進(jìn)行驗(yàn)證,驗(yàn)證后立即“忘記”密碼(不保存)。

所以,用戶的真實(shí)密碼既不應(yīng)該保存在Cookie里,也不應(yīng)該保存在Session里。

絕對(duì)不要將用戶的真實(shí)密碼和賬號(hào)保存在Cookie或Session中! 這是Web安全的基本原則。

六.requests模塊中cookies和session的作用

在 requests 進(jìn)行登錄時(shí),賬戶和密碼是通過(guò) POST 請(qǐng)求的 data 參數(shù)發(fā)送的。

data參數(shù)接受一個(gè)字典

我們之前討論過(guò),Cookie和Session不是用來(lái)存儲(chǔ)密碼的,而是用來(lái)維護(hù)會(huì)話狀態(tài)的。在requests庫(kù)中,Cookie和Session的作用如下:

  • Session對(duì)象:在requests庫(kù)中,Session對(duì)象允許你跨請(qǐng)求保持某些參數(shù),比如Cookie、頭部信息等。它最常用的功能就是保持登錄狀態(tài)(通過(guò)自動(dòng)處理Cookie)。
  • Cookie:在HTTP請(qǐng)求中,Cookie是服務(wù)器發(fā)送到瀏覽器并保存在本地的一小段數(shù)據(jù),瀏覽器會(huì)在后續(xù)的請(qǐng)求中自動(dòng)攜帶這些數(shù)據(jù)。在requests中,你可以手動(dòng)為請(qǐng)求添加Cookie,但更常見(jiàn)的做法是使用Session對(duì)象自動(dòng)管理。

在爬蟲(chóng)中,我們通常使用Session來(lái)模擬登錄后的會(huì)話,步驟如下:

a. 創(chuàng)建一個(gè)Session對(duì)象。

b. 發(fā)送登錄請(qǐng)求(POST請(qǐng)求,包含用戶名和密碼),這個(gè)請(qǐng)求會(huì)返回一個(gè)包含Cookie的響應(yīng),Session會(huì)自動(dòng)保存這個(gè)Cookie。

c. 使用同一個(gè)Session對(duì)象發(fā)送后續(xù)請(qǐng)求,Session會(huì)自動(dòng)在請(qǐng)求中攜帶之前保存的Cookie,這樣服務(wù)器就認(rèn)為你已經(jīng)登錄了。

注意:我們不會(huì)將密碼存儲(chǔ)在Cookie或Session中,而是通過(guò)登錄請(qǐng)求將密碼(通常是加密的)發(fā)送給服務(wù)器,服務(wù)器驗(yàn)證后返回一個(gè)會(huì)話標(biāo)識(shí)(例如Session ID),這個(gè)標(biāo)識(shí)會(huì)保存在Cookie中,后續(xù)請(qǐng)求就靠這個(gè)標(biāo)識(shí)來(lái)維持登錄狀態(tài)。

requests.Session() 的作用

不是用來(lái)存儲(chǔ)密碼的,而是用來(lái)自動(dòng)管理HTTP會(huì)話狀態(tài)的:

import requests

# 創(chuàng)建會(huì)話對(duì)象
session = requests.Session()

# Session會(huì)自動(dòng):
# 1. 保持連接,提高性能
# 2. 自動(dòng)管理Cookies(服務(wù)器返回的)
# 3. 保持請(qǐng)求頭等信息的一致性

Session的實(shí)際工作方式:

# 第一次請(qǐng)求:登錄
login_data = {'username': 'user', 'password': 'pass'}
response = session.post('https://example.com/login', data=login_data)
# 服務(wù)器返回 Set-Cookie: session_id=abc123
# Session對(duì)象會(huì)自動(dòng)保存這個(gè)cookie

# 第二次請(qǐng)求:訪問(wèn)個(gè)人頁(yè)面
# Session會(huì)自動(dòng)在請(qǐng)求頭中添加: Cookie: session_id=abc123
profile_response = session.get('https://example.com/profile')
# 不需要手動(dòng)處理cookies!

Cookies 參數(shù)的作用

cookies 參數(shù)是用于手動(dòng)設(shè)置請(qǐng)求中的Cookie,而不是存儲(chǔ)密碼:

# 方式1:使用字典
cookies_dict = {'session_id': 'abc123', 'user_token': 'xyz789'}
response = requests.get(url, cookies=cookies_dict)

# 方式2:使用CookieJar
from http.cookies import SimpleCookie

cookie = SimpleCookie()
cookie['session_id'] = 'abc123'
cookie['session_id']['domain'] = 'example.com'
response = requests.get(url, cookies=cookie)

課本上實(shí)現(xiàn)第二種方式使用的是requests.cookies.RequestsCookieJar()類

完整的登錄流程示例

import requests

# 創(chuàng)建會(huì)話
session = requests.Session()

# 1. 首先可能需要獲取登錄頁(yè),獲取CSRF token等
login_page = session.get('https://example.com/login')
# 這里可以解析頁(yè)面獲取CSRF token

# 2. 準(zhǔn)備登錄數(shù)據(jù)(密碼只在這里短暫使用)
login_data = {
    'username': 'your_username', 
    'password': 'your_password',  # 密碼只在這里出現(xiàn)一次
    'csrf_token': '從登錄頁(yè)面獲取的token'
}

# 3. 發(fā)送登錄請(qǐng)求
login_response = session.post(
    'https://example.com/login', 
    data=login_data
)

# 登錄成功后,session自動(dòng)保存了服務(wù)器返回的認(rèn)證cookie
# 后續(xù)請(qǐng)求都會(huì)自動(dòng)攜帶這個(gè)cookie

# 4. 訪問(wèn)需要登錄的頁(yè)面(自動(dòng)攜帶cookies)
dashboard = session.get('https://example.com/dashboard')
profile = session.get('https://example.com/profile')

# 密碼變量現(xiàn)在可以清除了(雖然Python會(huì)自動(dòng)回收)
del login_data['password']

以上就是Python抓取靜態(tài)網(wǎng)頁(yè)數(shù)據(jù)的完整指南的詳細(xì)內(nèi)容,更多關(guān)于Python抓取靜態(tài)網(wǎng)頁(yè)數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python分布式庫(kù)celery處理大規(guī)模的任務(wù)并行化

    python分布式庫(kù)celery處理大規(guī)模的任務(wù)并行化

    Python中的分布式任務(wù)隊(duì)列時(shí),Celery是一個(gè)備受推崇的工具,它是一個(gè)功能強(qiáng)大的分布式系統(tǒng),可用于處理大規(guī)模的任務(wù)并行化,本文將介紹Celery的基本概念、用法和示例代碼,幫助讀者更好地了解和使用這個(gè)庫(kù)
    2024-01-01
  • Python3+Pycharm+PyQt5環(huán)境搭建步驟圖文詳解

    Python3+Pycharm+PyQt5環(huán)境搭建步驟圖文詳解

    這篇文章主要介紹了Python3+Pycharm+PyQt5環(huán)境搭建步驟圖文詳解,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-05-05
  • matplotlib 生成的圖像中無(wú)法顯示中文字符的解決方法

    matplotlib 生成的圖像中無(wú)法顯示中文字符的解決方法

    這篇文章主要介紹了matplotlib 生成的圖像中無(wú)法顯示中文字符的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Python中判斷子串存在的性能比較及分析總結(jié)

    Python中判斷子串存在的性能比較及分析總結(jié)

    這篇文章主要給大家總結(jié)介紹了Python中判斷子串存在的性能比較及分析的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Python使用Pandas讀取CSV文件數(shù)據(jù)的操作方法

    Python使用Pandas讀取CSV文件數(shù)據(jù)的操作方法

    Pandas?是?Python?中一個(gè)強(qiáng)大的數(shù)據(jù)分析庫(kù),它提供了大量的工具用于數(shù)據(jù)操作和分析,其中,read_csv?函數(shù)是?Pandas?中最常用的函數(shù)之一,用于從?CSV?文件中讀取數(shù)據(jù),本文將詳細(xì)介紹?read_csv?的基本用法,常見(jiàn)問(wèn)題及其解決方案,并通過(guò)代碼案例進(jìn)行說(shuō)明
    2024-12-12
  • python中的yield from語(yǔ)法快速學(xué)習(xí)

    python中的yield from語(yǔ)法快速學(xué)習(xí)

    在本篇文章里小編給大家整理的是一篇關(guān)于python中的yield from語(yǔ)法快速學(xué)習(xí)相關(guān)內(nèi)容,有興趣的朋友們可以參考下。
    2020-11-11
  • Python+API打造一個(gè)終端天氣預(yù)報(bào)工具

    Python+API打造一個(gè)終端天氣預(yù)報(bào)工具

    這篇文章主要為大家詳細(xì)介紹了如何利用Python和API打造一個(gè)終端天氣預(yù)報(bào)工具,支持城市查詢,天氣圖標(biāo),美化輸出,有需要的小伙伴可以了解一下
    2025-07-07
  • Python類如何定義私有變量

    Python類如何定義私有變量

    這篇文章主要介紹了Python類如何定義私有變量,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Python用20行代碼實(shí)現(xiàn)批量摳圖功能

    Python用20行代碼實(shí)現(xiàn)批量摳圖功能

    在日常的工作和生活中,我們經(jīng)常會(huì)遇到需要摳圖的場(chǎng)景,即便是只有一張圖片需要摳,也會(huì)摳得我們不耐煩。本文將為大家分享一個(gè)20行代碼就能實(shí)現(xiàn)是批量摳圖,需要的可以參考一下
    2022-05-05
  • docker django無(wú)法訪問(wèn)redis容器的解決方法

    docker django無(wú)法訪問(wèn)redis容器的解決方法

    今天小編就為大家分享一篇docker django無(wú)法訪問(wèn)redis容器的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08

最新評(píng)論

沙湾县| 香港| 宁夏| 顺昌县| 定远县| 陆良县| 肇州县| 嘉峪关市| 阜新市| 临汾市| 沿河| 兴文县| 阆中市| 宣城市| 无极县| 云阳县| 丰城市| 诸城市| 井陉县| 夏河县| 乐陵市| 西城区| 白沙| 万全县| 宁强县| 教育| 永春县| 定边县| 辽源市| 达州市| 长武县| 渑池县| 屯留县| 会宁县| 铜梁县| 宜州市| 台东市| 屏南县| 汾阳市| 贵港市| 衡东县|