Redis存儲Cookie實現爬蟲保持登錄 requests | selenium

前言

前面已經介紹了requests和selenium這兩種方式的基礎知識和模擬登錄,但是我們需要每次都進行登錄,這明顯是很麻煩并且不合理的,所以這次我分享一下怎么可以讓我們的程序進行一次登錄之后,和普通瀏覽器一樣下次不進行登錄直接進行對網站數據的爬取

下面的我分享的內容需要前置知識,如果同志有知識不理解,可以查看我以前寫的文章

Python爬蟲request三方庫實戰-CSDN博客

Python爬蟲 XPath 三方庫lxml-CSDN博客

Python爬蟲 模擬登錄 requests版-CSDN博客

selenium基礎知識 和 模擬登錄selenium版本-CSDN博客

目錄

保持登錄的核心原理

保持登錄request版本

保持登錄selenium版本


保持登錄的核心原理

市面上基本上所有的網站都把登錄的信息存儲到瀏覽器的Cookie里面了。

無論他使用什么方式進行登錄,基本上都要先拿到瀏覽器的請求頭Cookie信息作為依據給出登錄狀態的響應。

當然也有極少數的網站選擇請求頭Authorization信息作為依據給出登錄狀態的響應。

如果Cookie不可以,可以往這方面排查。

所以我們的核心操作就是在第一次模擬登錄的時候對Cookie進行存儲,然后以后對這個網站進行請求的時候帶上我們在第一次模擬登錄的時候獲取的請求頭。

請求頭Authorization信息也是同樣的思路,只是存儲和獲取的請求頭不一樣,原理是相通的。

我下面把Cookie存儲到redis為例,給出代碼示例和詳細操作流程。

保持登錄request版本

在沒有反爬機制的情況下,我們直接拿到請求登錄接口返回的Cookie值,把它保存到一個地方

然后在我們請求這個網站的網址的時候帶上這個Cookie值就保證了登錄狀態了

因為請求登錄接口返回的Cookie值是一個對象,所以我們要進行二進制的序列化進行存儲

我存儲到Redis中為例

對redis數據庫進行鏈接

import redis#鏈接redis
redis_client = redis.StrictRedis(host='redis數據庫的IP',port=端口號,db=0,password='redis密碼',  # 添加密碼參數decode_responses=False  # 禁止自動解碼返回值為字符串,因為存儲是pickle序列化之后的二進制數據
)

將請求接口返回的Cookie值存儲到Redis中

import pickle# loginResponse是requests請求登錄接口的響應對象
# 因為loginResponse.cookie一個RequestsCookieJar類型,需要使用pickle進行序列化存儲到redis
# 存儲的時候使用pickle做一個序列化轉化為二進制進行存儲
redis_client.setex("Cookie", 86400, pickle.dumps(loginResponse.cookies))

從Redis中取出Cookie,請求網站網址的時候請求頭加上Cookie保持登錄

import pickle#嘗試從redis進行獲取Cookie
Cookie = redis_client.get("Cookie")#redis存儲的cookie是序列化的,所以要進行反序列化才能使用
Cookie = pickle.loads(Cookie)

完整示例

對某車市網站進行爬取

import requests
from lxml import etree
import pickle
import redis#鏈接redis
redis_client = redis.StrictRedis(host='redis數據庫的IP',port=redis數據庫端口號,db=0,password='redis數據庫密碼',  # 添加密碼參數decode_responses=False  # 禁止自動解碼返回值為字符串,因為存儲是pickle序列化之后的二進制數據
)url = "目標請求網址"headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
}#嘗試從redis進行獲取cheshiCookie
cheshiCookie = redis_client.get("cheshiCookie")if cheshiCookie:#redis存儲的cookie是序列化的,所以要進行反序列化才能使用cheshiCookie = pickle.loads(cheshiCookie)#redis存儲的cookie是序列化的,所以要進行反序列化才能使用cheshiCookie = pickle.loads(cheshiCookie)res1 = requests.get(url, headers=headers, cookies=cheshiCookie)
else:res1 = requests.get(url, headers=headers)datas = etree.HTML(res1.text)
#獲取頁面是否有登錄頁面的特征,我這里使用XPath定位《賬號登錄》這個文本是否可以獲取到來判斷這個頁面是不是登錄頁面
loginName = datas.xpath('//div[@class="userlogin"]//span[2]/text()')#這個頁面可以獲取賬號登錄這個文本,說明是登錄頁面,需要進行登錄
if loginName and loginName[0] == "賬號登錄":loginUrl = "登錄接口"loginData = {"key1": "value1","key2": "value2","key3": "value3"}loginResponse = requests.post(loginUrl, data=loginData, headers=headers)# 因為loginResponse.cookie一個RequestsCookieJar類型,需要使用pickle進行序列化存儲到redisredis_client.setex("cheshiCookie", 86400, pickle.dumps(loginResponse.cookies))#再次請求需要登錄的請求地址,加上Cookie,此時就是登錄狀態了res2 = requests.get(url, headers=headers,cookies=loginResponse.cookies)print(res2.text)
else:print(res1.text)

如果網址的Cookie不是從登錄接口響應的時候直接給你的,給一些原材料進行加密處理,這個時候要進行自行探索了,原理就是得到Cookie存儲起來,下次請求網址的時候帶上,保持登錄狀態進行請求?

保持登錄selenium版本

因為Requests方式進行保持登錄,網站登錄接口稍微有點加密就基本上搞不了了。

所以我們還有一種簡單粗暴的方式,控制瀏覽器,進行登錄,登錄完成之后會跳轉登錄之后的頁面,把登錄之后的頁面上的Cookie直接存儲到Redis中。

就跟真人取瀏覽器上面登錄狀態網站的Cookie是一樣的

因為是直接從瀏覽器的網址上面拿到的Cookie,所以是一個JSON字符串,需要序列化成JSON字符串進行存儲到Redis

對Redis數據庫進行鏈接

import redis#鏈接redis
redis_client = redis.StrictRedis(host='redis數據庫的IP',port=端口號,db=0,password='redis密碼',  # 添加密碼參數decode_responses=True  # 禁止自動解碼返回值為字符串,因為存儲是pickle序列化之后的二進制數據
)

將拿到的Cookie序列化成JSON字符串存儲到Redis中

# 序列化成 JSON 字符串并存入 Redis
redis_client.set("Cookie", json.dumps(cookies))

從Redis中取Cookie并還原成JSON字符串,并注入到當前selenium瀏覽器驅動driver中

一定要先打開請求網址再注入Cookie,注入的Cookie是指對當前頁面進行Cookie注入

import json#獲取redis里面存儲cookie的json字符串
Cookie = redis_client.get("Cookie")
cookies = json.loads(Cookie)
# 逐個注入 Cookie
for cookie in cookies:driver.add_cookie(cookie)

完整示例

?對某淘網站的商品信息進行爬取

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as EC
import redis
import json#鏈接redis
redis_client = redis.StrictRedis(host='redis數據庫IP',port=redis數據庫端口,db=0,password='redis數據庫密碼',  # 添加密碼參數decode_responses=True  # 自動解碼返回值為字符串
)
#獲取redis里面存儲cookie的json字符串
taobaoCookie = redis_client.get("taobaoCookie")# selenium 4的寫法
options = Options()
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36")
options.add_argument("--window-size=1920,1080")  # 設置窗口大小
options.add_argument("--disable-blink-features=AutomationControlled")  # 禁用自動化控制特征
options.add_argument("--disable-infobars")  # 禁用提示條
options.add_argument("--no-sandbox")  # 解決DevToolsActivePort文件不存在的報錯
options.add_argument("--disable-dev-shm-usage")  # 禁用共享內存
options.add_argument("--disable-extensions")  # 禁用擴展
options.add_argument("--disable-gpu")  # 禁用GPU加速
options.add_argument("--disable-javascript")  # 禁用JavaScript(根據需求調整)
options.add_argument("--incognito")  # 隱身模式
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager(driver_version="谷歌瀏覽器版本號").install()),options=options)
driver.get("目標請求網址")
#如果redis獲取到taobaoCookie就加上,沒有后面登錄獲取
if taobaoCookie:cookies = json.loads(taobaoCookie)# 逐個注入 Cookiefor cookie in cookies:driver.add_cookie(cookie)#看是否可以獲得網站標簽來確定網站是否加載完畢
title = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH,'//h1[@class="xM6AVLCbLn--mainTitle--_90838ca f-els-2"]')))#獲取一鍵登錄的標簽,這里使用了返回集合標簽的方法,因為有可能獲取不到,返回空集合,不至于報錯
loginHTML = driver.find_elements(By.XPATH,'//span[@class="xM6AVLCbLn--loginBtn--_3aec1d3"]')if not loginHTML:#發現沒有一鍵登錄標簽說明已經登錄了pass
else:#有一鍵登錄標簽需要登錄,并把登錄的Cookie信息存儲到redis用來下次使用#這一步也可以防止Cookie登錄失效,失效了和沒有Cookie是一樣的也會到這一步actions = ActionChains(driver).click(loginHTML[0]).perform()usern = driver.find_element(By.XPATH,'//input[@id="fm-login-id"]')pwd = driver.find_element(By.XPATH,'//input[@id="fm-login-password"]')loginHb = driver.find_element(By.XPATH,'//button[@class="fm-button fm-submit password-login  button-low-light"]')ActionChains(driver).click(usern).pause(1).send_keys('用戶名').pause(0.5).perform()ActionChains(driver).click(pwd).pause(1).send_keys('密碼').pause(0.5).perform()ActionChains(driver).click(loginHb).perform()resFlag = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH,'//div[@class="xM6AVLCbLn--tabDetailWrap--_3622a08"]')))# 獲取 Cookies(列表形式)cookies = driver.get_cookies()# 序列化成 JSON 字符串并存入 Redisredis_client.set("taobaoCookie", json.dumps(cookies))#把這個商品的所有顏色和大小搭配全部獲取下來
skuColorHTMLList = driver.find_elements(By.XPATH,'//div[@class="xM6AVLCbLn--skuWrapper--e63a4df5"]//div[@class="xM6AVLCbLn--skuItem--_68c0cae"][1]//div[contains(@class,"xM6AVLCbLn--valueItem--ee898cc0")]')
skuSizeHTMLList = driver.find_elements(By.XPATH,'//div[@class="xM6AVLCbLn--skuWrapper--e63a4df5"]//div[@class="xM6AVLCbLn--skuItem--_68c0cae"][2]//div[contains(@class,"xM6AVLCbLn--valueItem--ee898cc0")]')for skuColorHTML in skuColorHTMLList:#先點擊顏色分類actions = ActionChains(driver).click(skuColorHTML).perform()for skuSizeHTML in skuSizeHTMLList:#后點擊大小分類actions = ActionChains(driver).click(skuSizeHTML).perform()#過濾獲取值存儲,這里省略#最后關閉瀏覽器
driver.quit()

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

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

相關文章

leetcode:474. 一和零[01背包][動態規劃]

學習要點 給定背包容量&#xff0c;裝滿背包最多有多少個物品深入理解01背包深入理解動態規劃 題目鏈接 474. 一和零 - 力扣&#xff08;LeetCode&#xff09; 題目描述 解法:01背包 class Solution { public:int findMaxForm(vector<string>& strs, int m, int …

UE5 使用過程遇到的問題

切換緩存位置 進入界面&#xff0c;選擇-編輯-編輯器偏好設置搜索緩存&#xff0c;找到通用全局&#xff0c;修改本地DCC路徑到要切換的位置 閃退報錯 Fatal: Failed to get dll export function: cuvidGetDecoderCaps [NVDEC] 因為NVIDIA驅動沒有卸載干凈&#xff0c;使用D…

2025 BSidesMumbaiCTF re 部分wp

XORyy 附件拖入ida。明文 idkwhattonamethis 附件拖入ida 前三個函數都是檢查環境&#xff0c;跳過即可 長度為5&#xff0c;可以根據flag格式求解。腳本。盡管多解但是可能的結果很少 Diff_EQ 附件拖入ida z3求解等式&#xff0c;腳本。無反調試的情況下本地可以驗證&#xff…

圖靈完備之路(數電學習三分鐘)----邏輯與計算架構

經過前面幾節的學習&#xff0c;我們已經有了簡單的數電知識&#xff0c;下面&#xff0c;我們將正式進入設計簡單圖靈完備機的工作&#xff0c;首先&#xff0c;我們要設計出具有邏輯運算與計算功能的簡單結構&#xff1a; 1.邏輯架構 首先&#xff0c;該架構能實現多種邏輯…

【C++筆記】AVL樹的深度剖析

【C筆記】AVL樹的深度剖析 &#x1f525;個人主頁&#xff1a;大白的編程日記 &#x1f525;專欄&#xff1a;C筆記 文章目錄【C筆記】AVL樹的深度剖析前言一. AVL樹的概念二.AVL樹的實現2.1 AVL樹的結構2.2 AVL樹的插入2.3 平衡因子更新三.旋轉3.1旋轉的原則3.2右單旋3.3左單…

支持向量機(SVM)在肝臟CT/MRI圖像分類(肝癌檢測)中的應用及實現

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#, Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開…

DeepSeek掃雷游戲網頁版HTML5(附源碼)

用DeepSeek幫忙生成一個網頁版的掃雷游戲&#xff0c;效果非常棒&#xff0c;基于HTML5實現&#xff0c;方便運行。 提示詞prompt 幫我做一個網頁版的 html5 掃雷游戲游戲功能說明 游戲難度&#xff1a; 1 簡單&#xff1a;1010 格子&#xff0c;10個地雷 2 中等&#xff1a;16…

Day53GAN對抗生成網絡思想

生成對抗網絡&#xff08;GAN&#xff09;是深度學習領域的一種革命性模型&#xff0c;由Ian Goodfellow等人于2014年提出。其核心思想源于博弈論中的零和博弈&#xff0c;通過兩個神經網絡&#xff08;生成器和判別器&#xff09;的對抗性訓練&#xff0c;實現數據的高質量生成…

meilisearch-輕量級搜索引擎

meilisearch是一款開源的輕量級搜索引擎&#xff0c;相比于elasticsearch等重量級搜索引擎&#xff0c;meilisearch注重數據搜索&#xff0c;從而而省去了其它不必要的功能&#xff08;如支持聚合分析、分布式搜索等特性&#xff09;&#xff0c;以便于快速上手開發和構建應用。…

51c大模型~合集150

我自己的原文哦~ https://blog.51cto.com/whaosoft/14034001 #原來Scaling Law還能被優化 Meta這招省token又提效 2017 年&#xff0c;一篇《Attention Is All You Need》論文成為 AI 發展的一個重要分水嶺&#xff0c;其中提出的 Transformer 依然是現今主流語言模型…

每天一個前端小知識 Day 23 - PWA 漸進式 Web 應用開發

PWA 漸進式 Web 應用開發&#xff08;離線緩存、桌面安裝等&#xff09; &#x1f9e0; 一、什么是 PWA&#xff1f; PWA&#xff08;Progressive Web App&#xff09;是一種讓 Web 應用具有類似原生 App 用戶體驗的技術體系。 PWA 不是一個框架&#xff0c;而是由一組瀏覽器 A…

音視頻會議服務搭建(設計方案-兩種集成方案對比)-03

前言在開始計劃之前&#xff0c;查閱了不少資料。一種方案是 Go層做信令業務&#xff0c;nodejs層來管理和mediasoup的底層交互&#xff0c;通過客戶端去調用Go層&#xff1b;第二種方案是 客戶端直接調用nodejs層來跟mediasoup去交互&#xff1b; 最終&#xff0c;當然不出意料…

【小白】linux安裝ffmpeg | java轉碼 【超詳細】

前言 最近在開發過程中&#xff0c;發現當我們上傳除了mp4以外的其他少見的格式&#xff0c;如 .flv .rmvb 格式的視頻時&#xff0c;在前端在線播放的時候會播放不出來畫面&#xff0c;所以 接下來&#xff0c;將要進行一個非常完美的工程&#xff0c;將視頻格式轉為.mp4 1.安…

一個簡單的腳本,讓pdf開啟夜間模式

因為平常我比較喜歡晚上看面試題。 市面上很多的面試題pdf都是白色的晚上看的話非常的刺眼。 所以我本能的去互聯網搜索看看有沒有pdf轉換為夜間模式的。 搜索了一段時間后發現并沒有這種東西。于是我自己做了一個轉換的python腳本。 import os import fitz # PyMuPDF from P…

Flink OceanBase CDC 環境配置與驗證

一、OceanBase 數據庫核心配置 1. 環境準備與版本要求 版本要求&#xff1a;OceanBase CE 4.0 或 OceanBase EE 2.2組件依賴&#xff1a;需部署 LogProxy 服務&#xff08;社區版/企業版部署方式不同&#xff09;兼容模式&#xff1a;支持 MySQL 模式&#xff08;默認&#x…

c++對象池

【設計模式】其它經典模式-對象池模式&#xff08;Object Pool Pattern&#xff09;-CSDN博客 在C中&#xff0c;對象池&#xff08;Object Pool&#xff09;是一種管理對象生命周期的技術&#xff0c;旨在減少對象創建和銷毀的開銷&#xff0c;提高性能。對象池預先分配一定數…

JavaFX:Scene(場景)

簡介 Scene對象是JavaFX場景圖的根(root)。JavaFX 場景中包含所有可視的 JavaFX GUI 組件。JavaFX 場景由javafx.scene.Scene類表示。必須在 Stage(舞臺)上設置 Scene 對象才能使其可見。在本 JavaFX Scene 教程中,將向您展示如何創建 Scene 對象并向其添加 GUI 組件。 創…

vue3.4中的v-model的用法~

1.首先以前我們針對父子組件傳參是不是通過defineProps與defineEmits來實現的&#xff0c;但是這么比較繁瑣&#xff0c;因為他是單向傳參&#xff0c;而不是雙向的&#xff0c;這里我們要介紹的是vue3.4的v-model來實現雙向數據傳遞。 2、代碼示例&#xff1a; //父組件 <…

nvm常用指令匯總

nvm是用來管理nodejs的&#xff0c;可以方便安裝、切換、卸載當前環境的node版本。 以下是常用指令匯總&#xff1a;nvm list 查看本機已經安裝的node版本。*表示當前系統正在使用的node版本nvm install xx.xx.x 后邊加版本號&#xff0c;表示安裝指定的版本nvm use xx.xx.x當前…

洛谷P5021 [NOIP 2018 提高組] 賽道修建【題解】【二分答案+樹上貪心】

P5021 [NOIP 2018 提高組] 賽道修建 題意簡述 給定一棵含 n n n 個點的無向帶權樹&#xff0c;求將其分裂為 m m m 條鏈后&#xff0c;最短的一條鏈的最大長度是多少&#xff1f; 點可以重復使用&#xff0c;邊不可以重復使用。 思路 二分答案貪心判定貌似可以&#xff…