如何避免爬蟲因Cookie過期導致登錄失效

1. Cookie的作用及其過期機制

1.1 什么是Cookie?

Cookie是服務器發送到用戶瀏覽器并保存在本地的一小段數據,用于維持用戶會話狀態。爬蟲在模擬登錄后,通常需要攜帶Cookie訪問后續頁面。

1.2 Cookie為什么會過期?

  • 會話Cookie(Session Cookie):瀏覽器關閉后失效。
  • 持久Cookie(Persistent Cookie):設置**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Expires</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Max-Age</font>**屬性,超時后失效。
  • 服務器主動失效:如用戶修改密碼、長時間未操作等。

如果爬蟲未正確處理Cookie過期問題,會導致:

  • 請求返回**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">401/403</font>**狀態碼
  • 被重定向到登錄頁面
  • 觸發網站反爬機制(如封禁IP)

2. 檢測Cookie是否過期的策略

2.1 直接檢測HTTP響應

  • 檢查返回狀態碼(如**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">302</font>**重定向到登錄頁)。
  • 檢查響應內容是否包含登錄提示(如**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">"請先登錄"</font>**)。
import requestsdef check_cookie_valid(session):test_url = "https://example.com/user/profile"  # 需要登錄才能訪問的頁面response = session.get(test_url)if response.status_code == 200 and "個人中心" in response.text:return True  # Cookie有效else:return False  # Cookie失效

2.2 檢查Cookie的Expires屬性

如果服務器返回的Cookie帶有**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Expires</font>**字段,可以解析并判斷是否已過期。

from datetime import datetimedef is_cookie_expired(cookie):if "expires" in cookie:expires_time = datetime.strptime(cookie["expires"], "%a, %d-%b-%Y %H:%M:%S GMT")return expires_time < datetime.now()return False  # 無過期時間或會話Cookie

3. 自動刷新Cookie的解決方案

3.1 重新登錄獲取新Cookie

當檢測到Cookie失效時,自動調用登錄接口更新Cookie。

def login(username, password):login_url = "https://example.com/login"session = requests.Session()payload = {"username": username, "password": password}response = session.post(login_url, data=payload)if "登錄成功" in response.text:return session  # 返回帶新Cookie的Sessionelse:raise Exception("登錄失敗")

3.2 使用Session對象持久化Cookie

**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">requests.Session()</font>**可自動管理Cookie,但需結合存儲機制(如文件、數據庫)實現長期有效。

import pickledef save_session(session, filename="session.pkl"):with open(filename, "wb") as f:pickle.dump(session.cookies, f)def load_session(filename="session.pkl"):session = requests.Session()try:with open(filename, "rb") as f:session.cookies.update(pickle.load(f))except FileNotFoundError:pass  # 首次運行無緩存return session

3.3 結合Redis緩存Cookie(分布式爬蟲適用)

import redis
import pickleredis_client = redis.StrictRedis(host="localhost", port=6379, db=0)def save_session_to_redis(session, key="example_cookie"):redis_client.set(key, pickle.dumps(session.cookies))def load_session_from_redis(key="example_cookie"):session = requests.Session()cookie_data = redis_client.get(key)if cookie_data:session.cookies.update(pickle.loads(cookie_data))return session

4. 進階優化方案

4.1 使用Selenium處理動態Cookie

某些網站采用JavaScript動態生成Cookie,可使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">selenium</font>**模擬瀏覽器登錄。

from selenium import webdriver
from selenium.webdriver.common.by import Bydef selenium_login(username, password):driver = webdriver.Chrome()driver.get("https://example.com/login")driver.find_element(By.NAME, "username").send_keys(username)driver.find_element(By.NAME, "password").send_keys(password)driver.find_element(By.XPATH, "//button[@type='submit']").click()# 獲取Cookie并轉為requests可用的格式cookies = driver.get_cookies()session = requests.Session()for cookie in cookies:session.cookies.set(cookie["name"], cookie["value"])driver.quit()return session

4.2 結合代理IP和User-Agent輪換

避免因頻繁登錄觸發反爬。

import requests
from requests.auth import HTTPProxyAuth# 爬蟲配置
LOGIN_URL = "https://example.com/login"  # 登錄頁面的 URL
DATA_URL = "https://example.com/data"    # 需要爬取數據的 URL
USERNAME = "your_username"               # 用戶名
PASSWORD = "your_password"               # 密碼# 代理配置
proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"# 構造代理地址
proxies = {"http": f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}","https": f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}",
}# 請求頭
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
}# 登錄函數
def login():session = requests.Session()login_data = {"username": USERNAME,"password": PASSWORD}response = session.post(LOGIN_URL, data=login_data, headers=headers, proxies=proxies, auth=HTTPProxyAuth(proxyUser, proxyPass))if response.status_code == 200:print("登錄成功,獲取到新的 Cookie")return sessionelse:print("登錄失敗")return None# 檢測 Cookie 是否過期
def check_cookie(session):response = session.get(DATA_URL, headers=headers, proxies=proxies)if response.status_code == 401 or response.status_code == 403:print("Cookie 過期,需要重新登錄")return Falseelif "登錄已失效" in response.text:print("Cookie 過期,需要重新登錄")return Falseelse:print("Cookie 仍然有效")return True# 主爬蟲邏輯
def main():session = login()  # 首次登錄獲取 Cookieif session is None:print("無法登錄,爬蟲終止")returnwhile True:if check_cookie(session):  # 檢測 Cookie 是否過期# 如果 Cookie 有效,繼續爬取數據response = session.get(DATA_URL, headers=headers, proxies=proxies)if response.status_code == 200:print("成功獲取數據")# 處理數據print(response.text)else:print("數據獲取失敗")else:# 如果 Cookie 過期,重新登錄session = login()if session is None:print("重新登錄失敗,爬蟲終止")breakif __name__ == "__main__":main()

5. 結論

  • Cookie過期檢測:通過狀態碼、頁面內容或**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Expires</font>**字段判斷。
  • 自動刷新Cookie:重新登錄或使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Session</font>**持久化存儲。
  • 分布式爬蟲:可采用Redis共享Cookie,避免重復登錄。
  • 動態網站:結合**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">selenium</font>**獲取動態生成的Cookie。

通過合理管理Cookie,爬蟲可以長期穩定運行,避免因登錄失效導致的數據抓取中斷。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903154.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903154.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903154.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

matlab simulink中理想變壓激磁電流容易有直流偏置的原因分析。

simulink把線性變壓器模塊拉出來&#xff0c;設置沒有繞線電阻的變壓器&#xff0c;激磁電感和Rm都有&#xff0c;然后給一個50%占空比的方波&#xff0c;幅值正負10V&#xff0c;線路中設置一個電阻&#xff0c;模擬導線阻抗。通過示波器觀察激磁電流&#xff0c;發現電阻越小…

電力系統失步解列與振蕩解析

一、基本概念解析 1. 失步&#xff08;Out-of-Step&#xff09; 在電力系統中&#xff0c;失步是指并列運行的同步發電機因功率失衡導致轉子間相對角度超過穩定極限&#xff0c;無法維持同步運行的狀態。具體表現為&#xff1a; 當系統發生短路、負荷突變或故障切除等擾動時&…

ctfhub-RCE

關于管道操作符 windows&#xff1a; 1. “|”&#xff1a;直接執行后面的語句。 2. “||”&#xff1a;如果前面的語句執行失敗&#xff0c;則執行后面的語句&#xff0c;前面的語句只能為假才行。 3. “&”&#xff1a;兩條命令都執行&#xff0c;如果前面的語句為假則直…

Missashe考研日記-day28

Missashe考研日記-day28 1 專業課408 學習時間&#xff1a;2h學習內容&#xff1a; 今天先是預習了OS關于虛擬內存管理的內容&#xff0c;然后聽了一部分視頻課&#xff0c;明天接著學。知識點回顧&#xff1a; 1.傳統存儲管理方式特征&#xff1a;一次性、駐留性。2.局部性原…

01 appium環境搭建

環境搭建 Java JDKNode.jsAndroidStudio(提供sdk)appiumappium Inspector 相關安裝包下載 鏈接&#xff1a;https://pan.xunlei.com/s/VOOf3sCttAdHvlMkc7QygsoJA1# 提取碼&#xff1a;x4s5 AndroidStudio下載安裝sdk AndroidStudio下載 安裝運行&#xff0c;配置代理及測…

指針(4)

1.回調函數 回調函數就是通過函數指針調用的函數。 將函數的指針&#xff08;地址&#xff09;作為一個參數傳遞給另一個函數&#xff0c;當這個指針被調用其所指向的函數時&#xff0c;被調用的函數就是回調函數。回調函數不是由該函數的實現方直接調用&#xff0c;而是在特…

Raptor碼的解碼成功率matlab實現

下面是使用matlab實現關于Raptor 碼解碼成功率的仿真代碼&#xff0c;并繪制成功率隨編碼符號數量變化的圖形示例。代碼中包含了 Raptor 碼的預編碼&#xff08;使用稀疏矩陣乘法模擬&#xff09;、LT 編碼、解碼過程&#xff0c;以及解碼成功率的計算和繪圖。 具體代碼如下&am…

域名系統DNS

DNS介紹 DNS是一個域名系統&#xff0c;在互聯網環境中為域名和IP地址相互映射的一個分布式數據庫 &#xff0c; 能夠使用戶更方便的訪問互聯網&#xff0c;而不用去記住能夠被機器直接讀取的IP數串。類似于生活中的114服務&#xff0c;可以通過人名找到電話號碼&#xff0c;也…

Spark Streaming核心編程總結(四)

一、有狀態轉化操作&#xff1a;UpdateStateByKey 概念與作用 UpdateStateByKey 用于在流式計算中跨批次維護狀態&#xff08;如累加統計詞頻&#xff09;。它允許基于鍵值對形式的DStream&#xff0c;通過自定義狀態更新函數&#xff0c;將歷史狀態與新數據結合&#xff0c;生…

Dijkstra 算法代碼步驟[leetcode.743網絡延遲時間]

有 n 個網絡節點&#xff0c;標記為 1 到 n。 給你一個列表 times&#xff0c;表示信號經過 有向 邊的傳遞時間。 times[i] (ui, vi, wi)&#xff0c;其中 ui 是源節點&#xff0c;vi 是目標節點&#xff0c; wi 是一個信號從源節點傳遞到目標節點的時間。 現在&#xff0c;…

【java】lambda表達式總結

目錄 一、面向對象的處理方法 二、函數式編程的處理方法 先使用匿名內部類&#xff1a; lambda改造&#xff1a; lambda改造規則 示例&#xff1a; 三、補充&#xff1a;函數式接口 大家好&#xff0c;我是jstart千語。今天總結一下lambda表達式。lambda表達式在后面的s…

AtCoder Beginner Contest 242 G - Range Pairing Query (莫隊)

每周五篇博客&#xff1a;&#xff08;5/5&#xff09; 我做到了&#xff01; https://atcoder.jp/contests/abc242/tasks/abc242_g 這題主要是想給大家提供一份莫隊的板子&#xff0c;很多莫隊題基本上填空就差不多了&#xff08; 板子 void solve() {int n;std::cin >…

淘寶商品主圖標題api接口

1、輸入淘寶商品id或者鏈接&#xff0c;點查詢 2、查詢淘寶商品主圖&#xff0c;商品標題&#xff0c;商品價格&#xff0c;賣家旺旺 3、支持api接口

文心一言開發指南06——千帆大模型平臺新手指南

版權聲明 本文原創作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 千帆大模型平臺為新手用戶提供了一個全面的入門指南&#xff0c;以便用戶能夠快速熟悉平臺的操作和功能。千帆大模型平臺通過提供詳細的新手指南&#xff0c;確保用戶能夠順…

Pacman-N-queen

文檔 代碼及文檔&#xff1a;通過網盤分享的文件&#xff1a;code 鏈接: https://pan.baidu.com/s/1Rgo9ynnEqjZsSP2-6TyS8Q?pwdn99p 提取碼: n99p 補充核心代碼 核心代碼內容&#xff1a; genetic_algorithm,py # -*- coding: utf-8 -*- """ Created on …

常用的多傳感器數據融合方法

1. 概述 根據具體需求&#xff08;實時性、計算資源、噪聲特性&#xff09;選擇合適的方法&#xff0c;實際應用中常結合多種方法&#xff08;如UKF與神經網絡結合&#xff09;。 傳統方法 &#xff08;KF/EKF/UKF/PF&#xff09;依賴數學模型&#xff0c;適合動態系統&#…

簡單幾步,開啟 Intel VT-x 讓電腦“解開CPU封印”

#vmware #虛擬機 #cpu虛擬化 # Intel VT-x 前言 你是不是也遇到過這種情況&#xff1a;在嘗試運行虛擬機&#xff08;VM&#xff09;、安卓模擬器&#xff0c;或者使用 Windows 沙盒、WSL2 等功能時&#xff0c;遇到了類似“此主機支持 Intel VT-x&#xff0c;但 Intel VT-x …

Go語言--語法基礎4--基本數據類型--字符串類型

在 Go 語言中&#xff0c;字符串也是一種基本類型。相比之下&#xff0c; C/C 語言中并不存在原 生的字符串類型&#xff0c; 通常使用字符數組來表示&#xff0c;并以字符指針來傳遞。 Go 語言中字符串的聲明和初始化非常簡單&#xff0c;舉例如下&#xff1a; var str st…

QT中的事件及其屬性

Qt中的事件是對操作系統提供的事件機制進行封裝&#xff0c;Qt中的信號槽就是對事件機制的進一步封裝 但是特殊情況下&#xff0c;如對于沒有提供信號的用戶操作&#xff0c;就需要通過重寫事件處理的形式&#xff0c;來手動處理事件的響應邏輯 常見的Qt事件&#xff1a; 常見事…

socket套接字-UDP(中)

socket套接字-UDP&#xff08;上&#xff09;https://blog.csdn.net/Small_entreprene/article/details/147465441?fromshareblogdetail&sharetypeblogdetail&sharerId147465441&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link UDP服務器…