You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中Selenium与Requests/BeautifulSoup共享登录会话的技术问询

解决方法:同步Selenium的Cookie到Requests会话

这问题我之前踩过一模一样的坑!本质原因很简单:Selenium的Firefox会话和Requests的会话完全是独立的——你用浏览器登录时,网站把登录状态存在浏览器的Cookie里,但Requests默认是全新的会话,根本不知道这些Cookie,所以访问页面时自然显示未登录。

下面直接给你修改后的可运行代码,核心逻辑就是把Selenium浏览器里的登录Cookie提取出来,传给Requests的会话对象:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import config
import requests
from bs4 import BeautifulSoup

# 初始化Firefox浏览器(注意路径前面加r转义)
browser = webdriver.Firefox(executable_path=r"C:\Users\myUser\geckodriver.exe")
browser.get("https://www.mylink.com/")

# 登录操作(替换了原代码的硬等待,用显式等待更稳定)
timeout = 10
# 等待用户名输入框加载完成
login = WebDriverWait(browser, timeout).until(
    EC.presence_of_element_located((By.NAME, "sf-login"))
)
login.send_keys(config.USERNAME)

# 等待密码输入框加载完成
password = WebDriverWait(browser, timeout).until(
    EC.presence_of_element_located((By.NAME, "sf-password"))
)
password.send_keys(config.PASSWORD)

# 等待登录按钮可点击
button_log = WebDriverWait(browser, timeout).until(
    EC.element_to_be_clickable((By.XPATH, "/html/body/div[2]/div[1]/div/section/div/div[2]/form/p[2]/input"))
)
button_log.click()

# 等待登录完成(可以根据实际页面调整,比如等待登录后出现的专属元素)
WebDriverWait(browser, timeout).until(
    EC.url_changes("https://www.mylink.com/")
)

# 跳转到目标页面
name = "https://www.policytracker.com/auctions/page/"
browser.get(name)

# 等待并点击目标链接(这里替换你实际的N值)
N = 1
name2 = "/html/body/div[2]/div[1]/div/section/div/div[2]/div[3]/div[" + str(N) + "]/a"
title1 = WebDriverWait(browser, timeout).until(
    EC.element_to_be_clickable((By.XPATH, name2))
)
title1.click()

page = browser.current_url

# --------------------------
# 关键步骤:同步登录Cookie到Requests会话
# --------------------------
# 获取浏览器中存储的所有登录相关Cookie
cookies = browser.get_cookies()
# 创建Requests会话对象(自动维持会话状态)
session = requests.Session()
# 将每个Cookie完整添加到会话中(带上domain和path更严谨)
for cookie in cookies:
    session.cookies.set(
        cookie['name'], 
        cookie['value'], 
        domain=cookie.get('domain'),
        path=cookie.get('path')
    )

# 现在用带登录Cookie的会话访问页面,就能拿到已登录状态的内容了
r = session.get(page)
soup = BeautifulSoup(r.content, 'lxml')
print(soup)

# 最后别忘了关闭浏览器
browser.quit()

额外小贴士:

  1. 为什么用显式等待? 原代码的timeout=1太容易因为页面加载慢导致元素找不到,换成WebDriverWait能确保元素加载完成后再操作,稳定性提升很多。
  2. Cookie同步细节:除了namevalue,带上domainpath可以避免某些严格的网站拒绝无效Cookie。
  3. 替代方案:如果你的登录流程没有复杂的JS渲染(比如没有滑块验证码、动态生成的csrf token),其实可以直接用requests.post模拟登录,不用Selenium,效率会更高。但如果登录必须依赖浏览器JS,那还是得用Selenium先登录再同步Cookie的方式。

内容的提问来源于stack exchange,提问作者Rafał Szumski

火山引擎 最新活动