使用Python的Beautiful Soup和Selenium获取登录所需CSRF令牌的问题
使用Python的Beautiful Soup和Selenium获取登录所需CSRF令牌的问题
看起来你现在主要踩了两个坑:一是找错了承载CSRF令牌的元素,二是可能没等页面完全渲染就去抓取内容,咱们一步步来解决这个问题。
首先得纠正一个关键错误:你代码里在找的data-cf-beacon和CSRF令牌完全没关系,那个是Cloudflare的站点监控脚本元素,真正的CSRF令牌就像你一开始提到的,是在name="_token"的隐藏input标签里,比如<input type="hidden" name="_token" value="你的令牌值">。
然后,Selenium在无头模式下,页面的动态渲染可能需要一点时间,直接调用driver.page_source可能会漏掉还没生成的元素,所以最好用显式等待,等目标元素加载完成后再去获取,这样能大大提高成功率。
下面是修正后的完整代码,包含两种获取方式(Selenium直接定位、BeautifulSoup解析):
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup options = webdriver.ChromeOptions() # 无头模式配置 options.add_argument("--headless=new") # 避免无头模式下的权限/资源问题 options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") # 初始化浏览器 driver = webdriver.Chrome(options=options) driver.get("https://stockinvest.us/login?sref=ta-lock") try: # 显式等待:最多等10秒,直到CSRF令牌元素出现 csrf_element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.NAME, "_token")) ) # 获取令牌值 csrf_token = csrf_element.get_attribute("value") print(f"用Selenium直接获取的CSRF令牌: {csrf_token}") # 如果你想用BeautifulSoup解析的话,等页面加载完再拿源码 page_html = driver.page_source soup = BeautifulSoup(page_html, "html.parser") # 查找name为_token的input元素 soup_csrf = soup.find("input", {"name": "_token"}) if soup_csrf: print(f"用BeautifulSoup获取的CSRF令牌: {soup_csrf.get('value')}") finally: # 无论成功失败,都要关闭浏览器释放资源 driver.quit()
为什么你之前的代码没成功?
- 元素定位完全错误:你把注意力放在了
data-cf-beacon这个无关元素上,完全没对准真正的CSRF令牌载体 - 没有等待页面渲染:直接调用
driver.page_source时,页面可能还在动态加载,导致元素还没生成 - BeautifulSoup的查找语法错误:你写的
soup.find("data-cf-beacon", {"crossorigin": "anonymous"})是在找标签名为data-cf-beacon的元素,但实际这个是script标签的一个属性,语法完全不对
小技巧
下次遇到元素找不到的情况,先打开浏览器的检查工具(F12),右键目标元素:
- 选择「复制」→「复制选择器」/「复制XPath」,直接拿到可靠的定位语法
- 确认元素是否是动态加载的,如果是,一定要用Selenium的显式等待,而不是直接拿页面源码
备注:内容来源于stack exchange,提问作者Sagittarius A_Star
相关产品推荐
相关产品推荐

