如何用Selenium判断Discord是否需登录?解决同会话免登脚本异常
解决Discord网页端Selenium会话重复登录判断问题
问题描述
用Selenium访问discordapp.com/users/{user_id}({user_id}为个人Discord ID)时,首次会话流程正常:
- 加载URL后自动重定向至
discord.com/channels/@me - 弹出打开方式选择页,点击「Continue in browser」
- 显示登录表单,输入账号密码后点击「Log In」进入网页应用
但在同一个浏览器会话中多次运行函数时,无需再执行「Continue in browser」和登录步骤,导致Selenium的wait.until找不到对应元素,脚本直接停滞。
原代码如下:
import undetected_chromedriver as uc from fake_useragent import UserAgent from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as ec from selenium.webdriver.support.ui import WebDriverWait chrome_options = uc.options.ChromeOptions() prefs = {"credentials_enable_service": False, "profile.password_manager_enabled": False} chrome_options.add_experimental_option("prefs", prefs) chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') #chrome_options.add_argument('--headless=new') chrome_options.add_argument(f'user-agent={UserAgent().random}') driver = uc.Chrome(options=chrome_options) wait = WebDriverWait(driver, 10) def x_discord(user_id): driver.get(f"https://discordapp.com/users/{user_id}") try: wait.until(ec.visibility_of_element_located((By.XPATH, "//div[contains(text(), 'Continue in browser')]"))).click() wait.until(ec.visibility_of_element_located((By.NAME, "email"))).send_keys('login') wait.until(ec.visibility_of_element_located((By.NAME, "password"))).send_keys('password') wait.until(ec.visibility_of_element_located((By.XPATH, "//div[contains(text(), 'Log In')]"))).click() finally: wait.until(ec.url_contains("@me")) # rest of function... # driver.close() return result
已尝试的方法:
- 使用
wait.until(ec.url_to_be(url)),但重定向后URL始终固定为discord.com/channels/@me,无法区分登录状态 - 考虑添加计数器标记首次运行状态,但灵活性差,无法处理会话意外过期的情况
- 尝试用
driver.close()和driver.quit()重置会话,但无法重新启动新会话 - 读取localStorage的
email_cache判断登录状态,但实际运行中稳定性不足
可行优化方案
方案1:针对每个交互元素做存在性检查(try-except捕获超时)
核心逻辑:不再默认每次都需要执行登录流程,而是对每个需要点击/输入的元素单独做存在性验证,元素不存在则直接跳过,避免等待超时卡住脚本。
修改后的代码:
def x_discord(user_id): driver.get(f"https://discordapp.com/users/{user_id}") # 检查并点击「Continue in browser」按钮 try: continue_btn = wait.until(ec.visibility_of_element_located((By.XPATH, "//div[contains(text(), 'Continue in browser')]"))) continue_btn.click() except: # 元素不存在,跳过该步骤 pass # 检查并填写登录表单 try: email_input = wait.until(ec.visibility_of_element_located((By.NAME, "email"))) email_input.send_keys('your_login_email') password_input = wait.until(ec.visibility_of_element_located((By.NAME, "password"))) password_input.send_keys('your_login_password') login_btn = wait.until(ec.visibility_of_element_located((By.XPATH, "//div[contains(text(), 'Log In')]"))) login_btn.click() except: # 已处于登录状态,跳过登录流程 pass # 确保页面加载完成(等待目标URL或登录后专属元素) wait.until(ec.url_contains("@me")) # rest of function... return result
方案2:通过登录后专属元素判断状态
Discord登录成功后,页面会显示用户头像、侧边栏导航等专属元素,通过检查这些元素的存在性判断是否已登录,比依赖localStorage更可靠。
示例代码:
def is_logged_in(): try: # 检查登录后的用户头像元素(可根据实际页面结构调整XPATH/CSS选择器) wait.until(ec.visibility_of_element_located((By.XPATH, "//div[@class='avatarWrapper-1B9FTW']"))) return True except: return False def x_discord(user_id): driver.get(f"https://discordapp.com/users/{user_id}") if not is_logged_in(): # 处理「Continue in browser」弹窗 try: continue_btn = wait.until(ec.visibility_of_element_located((By.XPATH, "//div[contains(text(), 'Continue in browser')]"))) continue_btn.click() except: pass # 执行登录操作 wait.until(ec.visibility_of_element_located((By.NAME, "email"))).send_keys('your_login_email') wait.until(ec.visibility_of_element_located((By.NAME, "password"))).send_keys('your_login_password') wait.until(ec.visibility_of_element_located((By.XPATH, "//div[contains(text(), 'Log In')]"))).click() # 等待登录完成,直到检测到登录后元素 wait.until(is_logged_in()) # rest of function... return result
方案3:持久化浏览器会话(可选)
如果需要长期保持登录状态,可以在初始化Chrome时指定用户数据目录,让浏览器保留登录凭证,无需每次重复登录:
# Windows示例路径 chrome_options.add_argument(r"--user-data-dir=C:\Users\YourName\AppData\Local\Google\Chrome\User Data") # Linux/Mac示例路径 # chrome_options.add_argument(r"--user-data-dir=/home/yourname/.config/google-chrome/Default")
关键注意事项
- 避免硬编码元素定位符,Discord页面结构可能更新,建议定期检查XPATH/CSS选择器,优先使用稳定的属性(如ID、唯一类名)
- 根据网络情况调整
WebDriverWait的超时时间,避免因加载慢导致误判 - 使用
undetected_chromedriver时,确保其版本与本地Chrome版本匹配,避免兼容性问题
内容的提问来源于stack exchange,提问作者Jared Robertson
相关产品推荐
相关产品推荐

