项目场景:
下面是以虎扑网从NBA到公牛球队球队模拟点击的过程:
问题描述
执行程序时在第二次点击报错:
发生异常: NoSuchElementException
Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="ui-id-21"]"}
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from time import sleep
from selenium.webdriver.support.ui import WebDriverWait
service = Service(executable_path='./chromedriver.exe')
bro = webdriver.Chrome(service=service)
bro.get('https://www.hupu.com/') # 虎扑首页
sleep(0.5)
homepage_NBA = bro.find_element(By.XPATH, '//*[@id="container"]/div/div/div[1]/div[1]/div/div[2]/div[3]')
homepage_NBA.click() # 第一次点击
sleep(2)
NBA_rank = bro.find_element(By.XPATH, '//*[@id="ui-id-21"]')
NBA_rank.click() # 第二次点击
sleep(2)
rank_team = bro.find_element(By.XPATH, '/html/body/div[3]/div[2]/div[1]/ul/li[5]/a')
rank_team.click() # 第三次点击
sleep(2)
team_chicago = bro.find_element(By.XPATH, '/html/body/div[3]/div[3]/div[2]/div[2]/div[3]/div[2]/a[3]/div')
team_chicago.click() # 第四次点击
sleep(2)
chicago_player = bro.find_element(By.XPATH, '/html/body/div[3]/div[3]/div[1]/div[1]/h2/span[2]/a[2]')
chicago_player.click() # 第五次点击
sleep(3)
player_deroyzan = bro.find_element(By.XPATH, '/html/body/div[3]/div[4]/table/tbody/tr[3]/td[1]/a')
player_deroyzan.click() # 第六次点击
sleep(3)
bro.quit()
原因分析:
有可能是以下几个原因导致无法定位到元素:
该元素已经被修改或删除,不再出现在页面中。
该元素需要通过滚动页面才能被加载,但是你没有对页面进行滚动导致该元素无法被找到。
该元素所在的 iframe 中,你没有通过
switch_to.frame()
方法进入到正确的 iframe 中。通过增加显式等待的方式,等待元素在页面中出现或加载完毕后再进行查找
网络问题,网页没有被加载
最后,检查发现都不是这样问题,原因是点击后网页切换,xpath定位没有基于当前的页面进行定位,导致定位失败,一直错误。
解决方案:
获取当前浏览器所有窗口的句柄,并将光标切换到所对应的窗口页面。
在每次点击前加上:
allhandle = bro.window_handles
bro.switch_to.window(allhandle[1])
数字表示第几个窗口,1表示第二个窗口,2表示第三个窗口......
窗口判定为:
同理,比如 :诺贝尔奖官网一直点击到诺贝尔文学奖所有获得者的网页,由于始终在一个网页上,没有进行跳转,不需要进行句柄判断。
虎扑网正确代码为:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from time import sleep
from selenium.webdriver.support.ui import WebDriverWait
service = Service(executable_path='./chromedriver.exe')
bro = webdriver.Chrome(service=service)
bro.get('https://www.hupu.com/')
sleep(1)
#虎扑首页点击到NBA
homepage_NBA = bro.find_element(By.XPATH, '//*[@id="container"]/div/div/div[1]/div[1]/div/div[2]/div[3]')
homepage_NBA.click() # 执行后开启第二个窗口
sleep(2)
allhandle = bro.window_handles
bro.switch_to.window(allhandle[1]) # 第二个窗口 NBA页面
NBA_rank = bro.find_element(By.XPATH, '//*[@id="ui-id-21"]')
NBA_rank.click() # 执行后开启第三个窗口
sleep(2)
allhandle = bro.window_handles
bro.switch_to.window(allhandle[2]) # 第三个窗口 NBA球队排行榜
rank_team = bro.find_element(By.XPATH, '/html/body/div[3]/div[2]/div[1]/ul/li[5]/a')
rank_team.click() # 执行后还是在第三个窗口
sleep(2)
allhandle = bro.window_handles
bro.switch_to.window(allhandle[2]) # 第三个窗口 所有NBA球队
team_chicago = bro.find_element(By.XPATH, '/html/body/div[3]/div[3]/div[2]/div[2]/div[3]/div[2]/a[3]/div')
team_chicago.click() # 执行后开启第四个窗口
sleep(2)
allhandle = bro.window_handles
bro.switch_to.window(allhandle[3]) # 第四个窗口 公牛球队主页
chicago_player = bro.find_element(By.XPATH, '/html/body/div[3]/div[3]/div[1]/div[1]/h2/span[2]/a[2]')
chicago_player.click() # 执行后开启第五个窗口
sleep(2)
allhandle = bro.window_handles
bro.switch_to.window(allhandle[4]) # 第五个窗口 公牛球员主页
player_deroyzan = bro.find_element(By.XPATH, '/html/body/div[3]/div[4]/table/tbody/tr[3]/td[1]/a')
player_deroyzan.click() # 点击后进入最终的窗口
sleep(2)
bro.quit()
service.stop()
诺贝尔网代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from time import sleep
# 启动ChromeDriver服务
service = Service(executable_path='./chromedriver.exe')
driver = webdriver.Chrome(service=service)
driver.get('https://www.nobelprize.org/')
All_awards = driver.find_element(By.XPATH, '//*[@id="menu-item-28259"]/a')
All_awards.click()
sleep(2)
awards_Literature = driver.find_element(By.XPATH, '//*[@id="content"]/div/section[7]/article[1]/div/header/div/h2/a')
awards_Literature.click()
sleep(2)
all_Literature = driver.find_element(By.XPATH, '//*[@id="content"]/div/section[2]/article/div/p[4]/a[1]')
all_Literature.click()
sleep(5)
driver.quit()
service.stop()