Python3+Selenium获取session和token供Requests使用教程

本文介绍如何使用Selenium自动化登录系统,并从sessionStorage中提取SessionID和Token,适用于需要绕过密码构造和加密的场景。

一、背景说明

之前写了一款简单的api模糊测试工具,之前系统可以使用http Base认证现在改成session形式并加上了token。

最简单的改造方法,是自己先在浏览器手动登录,然后提取出session和token(系统token在整个会话期间可重复使用)填到模糊测试工具中即可。但这种非全自动化的方式不到万不得已不想用。

最直接的方法,最使用requests按登录流程依次发包登录即可。但其中的难点是密码是加密提交的,询问开发人员说是DES加密;DES加密不难,但是用不同的语言编写的加密算法与别人的结果完全一致那就比较费工夫。

最后的方法,那就是使用selenium登录避开密码的构造,这种方法的关键点在于:selenium是基于图形界面操作的,没有直接的办法能获取request和response的数据包,在这种情况下如何获取session和token。

自己动web前端的存储并没有很深入了解,一直想的是如何获取selenium request和response的数据包从中提取session和token,直到看到这篇文章才想起前端的变量(尤其是restful中的全局变量)会放存localStorage和sessionStorage中,从中提取session和token即可。

 

二、环境搭建

2.1 下载驱动

下载驱动文件,放到后续python文件同级目录下或加入到环境变量中即可。其中Chrome驱动要注意Driver版本与浏览器版本对应要求。

Firefox驱动下载地址:https://github.com/mozilla/geckodriver/releases

Chrome驱动下载地址:http://chromedriver.chromium.org/downloads

Safari驱动下载地址:https://webkit.org/blog/6900/webdriver-support-in-safari-10/

Edge驱动下载地址:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

 

2.2 安装selenium

pip install selenium

 

三、程序实现

3.1 系统状况

手动登录系统后,查看存储状况如下图所示,sessionid和token分别存储在sessionStorage的sessionId和token两个变量中

 

3.2 实现代码

复制代码

import json
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

class GetSessionAndToken():
    def __init__(self):
        # 启用无头模式,可选
        browser_options = webdriver.FirefoxOptions()
        browser_options.add_argument('--headless')
        browser_options.add_argument('--disable-gpu')
        self.browser = webdriver.Firefox(firefox_options=browser_options)
        # self.browser = webdriver.Chrome()

    # 登录系统,具体到自己系统时需要自行修改
    def login_system(self):
        # 登录用户名密码,改成目标系统用户名密码
        username = "admin"
        password = "123456"
        # 登录页面url,改成目标系统登录页面
        url = "https://10.10.6.93/#login"
        self.browser.get(url)
        # 显性等待,直到用户名控件加载出来才进行下一步
        WebDriverWait(self.browser,20,0.5).until(EC.presence_of_element_located((By.ID,"txtUserName")))
        # 填写用户名
        self.browser.find_element_by_id("txtUserName").send_keys(username)
        # 填写密码
        self.browser.find_element_by_id("txtPassword").send_keys(password)
        # 点击登录
        self.browser.find_element_by_id("btnLogin").click()
        # 强制等待5秒,待session和token都成功返回并存到浏览器中
        # restful隐性等待不太好用?self.browser.implicitly_wait(5)
        time.sleep(5)

    # 获取sessionid
    def get_sessionid(self):
        # 是要从localStorage中获取还是要从sessionStorage中获取,具体看目标系统存到哪个中
        # window.sessionStorage和直接写sessionStorage是等效的
        # 一定要使用return,不然获取到的一直是None
        # get的Item不一定就叫sessionId,得具体看目标系统把sessionid存到哪个变量中
        sessionid = self.browser.execute_script('return sessionStorage.getItem("sessionId");')

        # 另外sessionid一般都直接通过返回Set-Cookies头设置到Cookie中,所以也可以从Cookie读取
        # 获取浏览器所有Set-Cookie,返回对象是字典列表
        # cookies = self.browser.get_cookies()
        # 获取单项Cookie,是不是叫sessionId取决于系统存成什么变量,单项Cookie是字典
        # cookie = self.browser.get_cookie("sessionId")
        # cookie = cookie["value"]
        # print(f"{cookies}")
        return sessionid

    # 获取token
    def get_token(self):
        # 是要从localStorage中获取还是要从sessionStorage中获取,具体看目标系统存到哪个中
        # window.sessionStorage和直接写sessionStorage是等效的
        # 一定要使用return,不然获取到的一直是None
        # get的Item不一定就叫token,得具体看目标系统把token存到哪个变量中
        token = self.browser.execute_script('return sessionStorage.getItem("token");')
        # print(f"{token}")
        return token

    def __del__(self):
        # 退出程序时关闭浏览器
        self.browser.close()

if __name__ == "__main__":
    obj = GetSessionAndToken()
    obj.login_system()
    sessionid = obj.get_sessionid()
    token = obj.get_token()
    print(f"sessionid为: {sessionid}\n"
          f"token为:     {token}")

复制代码

 

3.3 实现效果

 

<think>好的,我现在需要帮助用户解决如何使用PythonSelenium获取浏览器访问某个页面的Token,然后用这个Token发起请求并下载文件的问题。首先,我得理解用户的具体需求。用户可能是在做自动化测试或者数据抓取,需要获取授权后的Token来访问受保护的资源。Token通常用于身份验证,比如JWT或者OAuth令牌,可能在HTTP请求的头部或者Cookie中。 接下来,我需要确定用户的使用场景。可能的情况是,用户需要登录一个网站,获取Token,然后用这个Token去下载文件。或者,用户访问的页面在加载时会通过API请求获取Token,然后使用Token进行后续的文件下载。这时候,用户希望自动化这个过程,避免手动操作。 用户可能遇到的问题包括:如何捕获浏览器中的Token,如何提取Token,以及如何用PythonRequests库携带Token发起请求下载文件。此外,用户可能对SeleniumRequests的结合使用不太熟悉,需要一步步的指导。 首先,思考如何用Selenium获取Token。通常Token可能出现在以下几种地方: 1. 页面源代码中的某个元素,比如隐藏的input字段。 2. 网络请求的响应头或请求头中,比如Authorization头。 3. 存储在浏览器的LocalStorage或SessionStorage中。 我需要逐一分析这些可能性,并给出对应的解决方案。例如,如果Token在LocalStorage中,可以通过执行JavaScript来获取;如果在网络请求中,可能需要使用Selenium的代理功能或者启用网络日志记录来捕获请求。 然后,考虑如何发起请求下载文件。使用Requests库是比较常见的方法,但需要正确设置请求头,包括携带Token。需要注意Token的格式,比如Bearer Token或者其他形式,以及是否需要处理Cookies。 接下来,需要编写示例代码,分步骤说明每个部分的作用。例如,启动浏览器、访问页面、获取Token、构造请求头、发送请求并保存文件。同时,要考虑到可能的错误处理,比如Token获取失败,或者下载请求返回错误状态码。 另外,用户可能关心如何处理动态加载的内容,是否需要等待页面加载完成,或者等待某个元素出现后再获取Token。这时候可能需要使用Selenium的显式等待功能,比如WebDriverWaitexpected_conditions。 还需要注意安全性问题,比如避免将Token硬编码在代码中,或者处理HTTPS请求时的证书问题。此外,下载文件时可能需要指定保存路径,并确保有足够的权限写入文件。 最后,总结步骤,强调关键点,比如Token获取方式可能因网站而异,需要根据具体情况调整代码。同时提醒用户遵守网站的使用条款,避免违法爬虫行为。</think>以下是通过Python的`selenium`获取页面Token并下载文件的逐步解决方案: --- ### **步骤1:启动浏览器并访问目标页面** ```python from selenium import webdriver from selenium.webdriver.chrome.service import Service # 配置浏览器驱动(需提前下载对应版本驱动) service = Service(&#39;chromedriver路径/chromedriver&#39;) # Windows改为chromedriver.exe driver = webdriver.Chrome(service=service) # 访问目标页面 driver.get("https://目标网站.com/login") ``` --- ### **步骤2:获取页面中的Token** 根据Token存储位置不同,分三种情况处理: #### **情况1:Token在页面元素中** ```python # 等待元素加载(示例定位隐藏的<input>) from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC token_element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "input[name=&#39;token&#39;]")) ) token = token_element.get_attribute("value") ``` #### **情况2:Token在LocalStorage** ```python token = driver.execute_script("return localStorage.getItem(&#39;tokenKey&#39;);") ``` #### **情况3:拦截网络请求获取Token(高级)** ```python # 启用网络日志记录(需Chrome 64+) from selenium.webdriver.common.desired_capabilities import DesiredCapabilities caps = DesiredCapabilities.CHROME caps[&#39;goog:loggingPrefs&#39;] = {&#39;performance&#39;: &#39;ALL&#39;} driver = webdriver.Chrome(desired_capabilities=caps) # 访问页面后过滤含Token的请求 logs = driver.get_log(&#39;performance&#39;) for entry in logs: log = json.loads(entry[&#39;message&#39;])[&#39;message&#39;] if &#39;Network.responseReceived&#39; in log[&#39;method&#39;]: url = log[&#39;params&#39;][&#39;response&#39;][&#39;url&#39;] if &#39;/api/token&#39; in url: # 根据实际API路径调整 request_id = log[&#39;params&#39;][&#39;requestId&#39;] response = driver.execute_cdp_cmd(&#39;Network.getResponseBody&#39;, {&#39;requestId&#39;: request_id}) token = json.loads(response[&#39;body&#39;])[&#39;token&#39;] ``` --- ### **步骤3使用Requests下载文件** ```python import requests headers = { "Authorization": f"Bearer {token}", # 根据实际Token格式调整 "User-Agent": "Mozilla/5.0" } # 发起下载请求 response = requests.get("https://目标网站.com/download", headers=headers) # 保存文件 with open("downloaded_file.pdf", "wb") as f: f.write(response.content) ``` --- ### **完整流程示例** ```python # 综合情况1 + 下载 from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import requests # 初始化浏览器 service = Service(&#39;/path/to/chromedriver&#39;) driver = webdriver.Chrome(service=service) try: # 访问登录页 driver.get("https://example.com/login") # 执行登录操作(根据实际情况填写) driver.find_element(By.ID, "username").send_keys("your_username") driver.find_element(By.ID, "password").send_keys("your_password") driver.find_element(By.ID, "submit-btn").click() # 获取Token token_element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "#token")) ) token = token_element.get_attribute("value") # 使用Requests下载 headers = {"Authorization": f"Token {token}"} response = requests.get("https://example.com/download", headers=headers) with open("data.zip", "wb") as f: f.write(response.content) print("文件下载完成!") finally: driver.quit() ``` --- ### **关键注意事项** 1. **等待机制**:使用`WebDriverWait`确保元素/数据加载完成 2. **Token格式**:根据实际需要调整`headers`中的Authorization格式 - Bearer Token: `f"Bearer {token}"` - Basic Auth: `requests.get(url, auth=(user, token))` 3. **反爬处理**:某些网站可能需要: - 添加完整的请求头复制(使用浏览器开发者工具查看) - 处理Cookie:`requests.Session()` + 同步Selenium Cookies 4. **大文件下载**:建议使用流式下载 ```python with requests.get(url, headers=headers, stream=True) as r: with open(&#39;large_file.iso&#39;, &#39;wb&#39;) as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk) ``` --- 如果需要处理特定网站的实际情况,可以提更多细节,我可以协助优化具体实现方案!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值