python - 使用 Selenium 登录网站时出现问题
问题描述
我正在尝试学习如何使用 Selenium 登录网站:Ingram-Micro。我制作了一个脚本,它在不同的页面上运行:https://news.ycombinator.com/login
.
现在我试图将同样的东西应用到 Ingram-Micro 上,但我被卡住了,我不知道还能尝试什么。我遇到的问题是一条错误/消息,指出提交元素不可点击,页面底部有一个接受 cookie 按钮,这似乎是导致问题的原因。
我试图解释它,但我总是收到错误说该元素不存在。但是,如果我不尝试单击接受 cookie 元素,我会收到原始错误,即提交按钮不可单击。这是我的代码:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException
import time
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
url = "https://usa.ingrammicro.com/_layouts/CommerceServer/IM/Login.aspx?
returnurl=//usa.ingrammicro.com/"
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)
def login():
USERNAME = 'email'
PASSWORD = 'password'
element = driver.find_element_by_link_text('I ACCEPT')
if element.is_displayed():
print("Element found")
element.click()
else:
print("Element not found")
driver.find_element_by_id('okta-signin-username').send_keys(USERNAME)
driver.find_element_by_id('okta-signin-password').send_keys(PASSWORD)
driver.find_element_by_id('okta-signin-submit').click()
login()
try:
me = driver.find_element_by_id("login_help-about")
print(f"{me.text} Element found")
except NoSuchElementException:
print('Not found')
driver.quit()
这是我得到的错误:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <input class="button button-primary" type="submit" value="Log in" id="okta-signin-submit" data-type="save"> is not clickable at point (365, 560). Other element would receive the click: <p class="cc_message">...</p>
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate
element: {"method":"link text","selector":"I ACCEPT"}
(Session info: headless chrome=84.0.4147.125)
解决方案
您面临的挑战是围绕脚本进行同步。
该站点上的事件链是 1) 页面已加载,2) 它启动了 javascript,3) 将 cookie 窗口滑动到视图中......
但是,页面加载后,selenium 不知道脚本,所以它认为它是好的。它试图在按钮出现之前点击它,并因为找不到它而感到不安。( NoSuchElementException
)
有不同的同步策略 - 这里的工作是 webdriverwait 告诉 selenium 等待(没有错误),直到您的对象达到指定的预期条件。
您可以在此处阅读有关等待和预期条件的更多信息
试试这个代码。对于cookie“我接受”按钮,我将标识符更改为xpath(因为我喜欢xpaths)并将其包装在webdriverwait中,等待对象可点击......
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
chrome_options = Options()
#chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
url = "https://usa.ingrammicro.com/_layouts/CommerceServer/IM/Login.aspx?returnurl=//usa.ingrammicro.com/"
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)
def login():
USERNAME = 'email'
PASSWORD = 'password'
element = WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.XPATH, '//a[text()="I ACCEPT"]')))
if element.is_displayed():
print("Element found")
element.click()
else:
print("Element not found")
driver.find_element_by_id('okta-signin-username').send_keys(USERNAME)
driver.find_element_by_id('okta-signin-password').send_keys(PASSWORD)
driver.find_element_by_id('okta-signin-submit').click()
login()
请注意,我必须删除无头以检查它是否有效,并且顶部还有 3 个额外的导入。
当您没有很多复杂的对象或具有不同等待条件的对象时,Webdriverwait 非常有用。
另一种同步和(在我看来更容易)是在脚本开始时设置一个隐式等待 ONCE - 这会配置驱动程序对象。
driver.implicitly_wait(10)
正如之前的链接所说:
隐式等待告诉 WebDriver 在尝试查找任何不立即可用的元素(或多个元素)时轮询 DOM 一段时间。默认设置为 0。一旦设置,就会在 WebDriver 对象的生命周期内设置隐式等待。
您可以像这样使用它.. 不做所有代码,只需在创建驱动程序并且代码工作后添加这一行:
.....
url = "https://usa.ingrammicro.com/_layouts/CommerceServer/IM/Login.aspx?returnurl=//usa.ingrammicro.com/"
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)
driver.implicitly_wait(10) # seconds
def login():
USERNAME = 'email'
PASSWORD = 'password'
element = driver.find_element_by_link_text('I ACCEPT')
if element.is_displayed():
print("Element found")
element.click()
else:
print("Element not found")
........
推荐阅读
- reactjs - Reactjs-无法访问tsx中函数内的类变量
- c++ - OpenCV 错误:重复中的断言失败(ny > 0 && nx > 0),文件 opencv/modules/core/src/copy.cpp,
- python - 如何将列表中的列表转换为Python中的字符串
- python - 熊猫日期时间转换将 .0 添加到列值
- python - 在列表上迭代函数
- swift - 模拟 AVCaptureDeviceInput 进行测试
- javascript - 加载模块时highcharts组织结构图抛出错误
- node.js - Jest 内存泄漏测试 Express 中间件
- flutter - 将从相机捕获的图像保存到图库中
- groovy - 方法没有签名:*** 适用于参数类型:() 值:[] 可能的解决方案:getRandomShippingMethod()