使用Python、Selenium和SeleniumBase关闭UPS网站上的退出Cookies弹窗
这是我正在使用的代码,目前我传入了一个假的追踪号码。我关闭了聊天窗口,然后尝试关闭饼干窗口。但不知道为什么,我就是无法点击那个X按钮,任何帮助都会非常感激。
这里的代码除了最后一行之外都能正常工作。你可以把它复制粘贴到一个.py文件里自己测试,只要你安装了正确的包。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException
import time
import os
import pandas as pd
import pyautogui
import undetected_chromedriver as uc
from seleniumbase import Driver
from selenium.webdriver.common.action_chains import ActionChains
# Add the driver options
driver = Driver(uc=True)
with driver:
# Go to the target website
driver.get("https://google.com")
driver.maximize_window()
#driver.set_window_size(1920, 820)
time.sleep(2)
driver.get("https://www.ups.com/track?track=yes&trackNums=1Z12345E1512345676&loc=en_US&requester=ST/")
time.sleep(3)
# Create another loop to run based on which element is found.
# Find UPS Element
U_Ele = driver.find_element(By.XPATH, "//span[contains(text(), 'UPS')]")
print(f"UPS Element found")
#Switch to UPS iframe
iframe = driver.find_element(By.XPATH, "//iframe[@id='inqChatStage']")
driver.switch_to.frame(iframe)
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="top-bar"]/div/div[1]/div[1]/topbar-element/div/div/div/div'))).click()
time.sleep(2)
driver.find_element(By.XPATH, '//button[@class="close_btn"]').click()
1 个回答
1
问题在于你切换到了IFRAME的上下文,但没有返回到原来的上下文。Selenium在IFRAME里面寻找关闭cookie面板的按钮。要把上下文切换回整个页面,你需要使用 driver.switch_to.default_content()
。
一些额外的建议:
- 尽量避免使用
time.sleep()
。这样会让你的脚本变慢,而且不如WebDriverWait
灵活。 - 要始终使用
WebDriverWait
。在每次与元素互动或调用.find_element()
时都应该使用等待。如果你要点击某个元素,就用EC.element_to_be_clickable()
。如果你要以其他方式与元素互动(比如获取.text
),就用EC.visibility_of_element_located()
。可以查看 文档,了解更多等待类型和其他信息。 - 你导航了两次……先是去谷歌,然后再去UPS网站。其实只需要导航一次就可以了。
- 保持你的导入清晰。你有两个不同的地方导入了
WebDriverWait
和一些你没有使用的其他导入。保持导入列表只包含必要的内容,可以减少代码量和编程时的困惑。 - 你应该优先使用
By.ID()
和By.CSS_SELECTOR()
,而不是XPaths。ID是最简单的,且不容易在页面上改变。CSS选择器比XPaths更快,语法也更简单。
考虑到这些,我把你的代码简化成了下面的可运行代码,
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
url = 'https://www.ups.com/track?track=yes&trackNums=1Z12345E1512345676&loc=en_US&requester=ST/'
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(url)
wait = WebDriverWait(driver, 5)
# switch to chat IFRAME and close chat
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, "inqChatStage")))
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[aria-label='End Chat']"))).click()
driver.switch_to.default_content()
# close cookies panel
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.implicit_consent span.ups-icon-x"))).click()
driver.quit()