You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium+Chrome无头模式下Upstox自动登录异常求助

问题:Chrome无头模式下Upstox自动登录无法触发OTP发送及页面跳转

环境配置:

  • Chrome浏览器 123.0.6312.58
  • chromedriver 123.0.6312.58
  • Selenium 4.14.0

现象:

  • 用Chrome无头模式访问https://login.upstox.com,输入手机号后点击「获取OTP」按钮,无法向手机发送OTP,页面也不跳转;但非无头模式运行完全正常。
  • Firefox无头模式在Windows环境可用,但Linux环境下同样失效;尝试Edge浏览器无头模式也未解决问题。

原代码:

import os
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from datetime import datetime
import requests


def init_chrome_webdriver():
    from selenium.webdriver.chrome.service import Service
    driver_path = os.path.join(os.getcwd(),'chromedriver.exe')
    service = Service(executable_path=driver_path,log_output="chromedriver.log")
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")
                         
    return webdriver.Chrome(service=service, options=options)

def automatic_login(config):

    url='https://login.upstox.com'
    driver = init_chrome_webdriver()
    driver.get(url)
    time.sleep(5)
    
    phone = driver.find_element(By.TAG_NAME,"input")
    phone.send_keys(config['phone'])
    page = driver.find_element(By.TAG_NAME,"body")
    page.screenshot("before.png")
    time.sleep(5)
    next = driver.find_element(By.ID,"getOtp")
    next.click()
    time.sleep(5)
    page = driver.find_element(By.TAG_NAME,"body")
    page.screenshot("after.png")
    driver.quit()

if __name__=='__main__':

    creds = {}
    creds['pass'] = ''
    creds['phone'] = 'xxxxxxxx'  #Replace with phone number

    automatic_login(creds)

解决方案

核心原因是Upstox的登录页面通过检测浏览器特征(如UA标识、窗口参数、自动化痕迹)拦截无头模式的自动化操作。以下是针对性修复:

1. 模拟真实浏览器特征

修改init_chrome_webdriver函数,添加窗口大小和真实UA,避免被识别为无头浏览器:

options.add_argument("--window-size=1920,1080")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36")

2. 禁用自动化检测标识

Chrome默认会暴露自动化相关特征,需要手动禁用:

options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)

3. 替换强制等待为显式等待

原代码的time.sleep()不稳定,改用Selenium显式等待确保元素加载完成后再操作,避免因页面未渲染完成导致点击失效:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 等待手机号输入框可交互
phone = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.TAG_NAME, "input"))
)

# 等待获取OTP按钮并点击
get_otp_btn = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, "getOtp"))
)
get_otp_btn.click()

# 等待OTP输入框出现,验证页面跳转
WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "input[placeholder='Enter OTP']"))
)

4. Linux环境额外配置

如果在Linux服务器运行,需安装浏览器依赖库:

# Chrome依赖
sudo apt-get install -y libnss3 libgconf-2-4 libxss1 libappindicator1 libindicator7

# Firefox依赖
sudo apt-get install -y libdbus-glib-1-2

修改后的完整代码

import os
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


def init_chrome_webdriver():
    from selenium.webdriver.chrome.service import Service
    driver_path = os.path.join(os.getcwd(),'chromedriver.exe')
    service = Service(executable_path=driver_path,log_output="chromedriver.log")
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")
    # 模拟真实浏览器参数
    options.add_argument("--window-size=1920,1080")
    options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36")
    # 禁用自动化检测
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
                         
    return webdriver.Chrome(service=service, options=options)

def automatic_login(config):
    url='https://login.upstox.com'
    driver = init_chrome_webdriver()
    driver.get(url)
    
    # 等待手机号输入框加载完成
    phone = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.TAG_NAME, "input"))
    )
    phone.send_keys(config['phone'])
    
    page = driver.find_element(By.TAG_NAME,"body")
    page.screenshot("before.png")
    
    # 等待并点击获取OTP按钮
    get_otp_btn = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.ID, "getOtp"))
    )
    get_otp_btn.click()
    
    # 验证页面跳转至OTP输入页
    try:
        WebDriverWait(driver, 15).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[placeholder='Enter OTP']"))
        )
        print("OTP页面加载成功")
    except Exception as e:
        print(f"页面跳转失败: {e}")
    
    page = driver.find_element(By.TAG_NAME,"body")
    page.screenshot("after.png")
    driver.quit()

if __name__=='__main__':
    creds = {}
    creds['pass'] = ''
    creds['phone'] = 'xxxxxxxx'  # 替换为真实手机号
    automatic_login(creds)

内容的提问来源于stack exchange,提问作者Ramesh N

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 04:32:20