解決Selenium彈出新頁面無法定位元素問題(Unable to locate element)

First

首先汽抚,簡書賬號和CSDN賬號都是我的,所以我依然是原創(chuàng)作者枕荞,因為喜歡簡書比較單純簡潔的格式柜候,所以我重心慢慢移向簡書。兩個依然會保持更新躏精,畢竟大家都是MarkDown編輯啊渣刷,復(fù)制粘貼不要太快,當(dāng)然矗烛,以后文章辅柴,簡書首發(fā)。


Python 2.7
IDE Pycharm 5.0.3

環(huán)境細(xì)節(jié)詳見Python+Selenium+PIL+Tesseract真正自動識別驗證碼進(jìn)行一鍵登錄

對于同一頁面無法定位元素問題請見姊妹篇解決網(wǎng)頁元素?zé)o法定位(NoSuchElementException: Unable to locate element)的幾種方法


 只解決一個問題--NoSuchElementException: Message: Unable to locate element

問題來源

在上一篇博客中瞭吃,我進(jìn)行了自動化登錄碌嘀,之后我想直接進(jìn)行對圖書的續(xù)約操作,但是利用元素定位的方法歪架,怎么都找不到元素股冗,我一直以為是我的規(guī)則用的不對,導(dǎo)致元素找不到和蚪,其實魁瞪,只是窗口句柄還停留在上一個頁面而已!對于新彈出的頁面還沒有定位;莺簟!峦耘!那怎么可能找得到在新頁面的元素呢L尢!!這是新手(我)犯下最大的錯誤辅髓,只顧于對元素方法的定位泣崩,卻沒有意識到頁面發(fā)生跳轉(zhuǎn)后的handles的變化。


解決方案

窗口重定位洛口,感謝@一朵菊花向陽開------python + selenium webdriver 從主窗口A跳轉(zhuǎn)至主窗口B后矫付,無法定位窗口B的元素的問題 讓我找到解決方案,最終得以實現(xiàn)句柄的重定位第焰!


(這段可跳過买优,因為百度太不穩(wěn)定了,測試結(jié)果有差別)

爆炸

但話說到這的時候挺举,我很疑惑一篇文章 python+selenuim webdriver 頁面跳轉(zhuǎn)后如何定位元素杀赢,他的方法我進(jìn)行測試時不可行的,請看測試湘纵;

他的代碼:我一行沒動進(jìn)行測試

#coding=utf-8

from selenium import webdriver
import time

browser=webdriver.Firefox()

browser.get("http://www.baidu.com")
browser.find_element_by_id("kw").send_keys("selenium")
browser.find_element_by_id("su").click()
time.sleep(3)
sreach_window=browser.current_window_handle  //此行代碼用來定位當(dāng)前頁面

browser.find_element_by_xpath("/html/body/div[3]/div[4]/div/div[3]/div[4]/h3/a").click()
time.sleep(5)

當(dāng)然如果我一點都不改脂崔,也是進(jìn)行不了測試的,這位大哥把注釋符號寫錯了梧喷,不是//砌左,而是#啊大哥
ok脖咐,然后運行下:出錯了

這里寫圖片描述

所以我感到好奇的是,這位大哥到底有沒有跑過這段代碼汇歹,看著原創(chuàng)的樣子應(yīng)該沒有抄襲才對啊屁擅,那應(yīng)該是測試過代碼才對,但是可重復(fù)性在哪秤朗?最后發(fā)現(xiàn)需要修改http成這樣才能訪問(大哥少加個/):
browser.get("https://www.baidu.com/")修改后代碼如下:

#coding=utf-8

from selenium import webdriver
import time

browser=webdriver.Firefox()

browser.get("https://www.baidu.com/")
browser.find_element_by_id("kw").send_keys("selenium")
browser.find_element_by_id("su").click()
time.sleep(1)
sreach_window=browser.current_window_handle #此行代碼用來定位當(dāng)前頁面
time.sleep(2)
browser.find_element_by_xpath("/html/body/div[3]/div[3]/div/div[3]/div[4]/h3/a").click()#我這里修改了一下div[4]煤蹭,大哥的索引直接到有道翻譯了,不利于下一步測試
time.sleep(1)

ok取视,這次能正常索引到值硝皂,但是!W魈贰稽物!我要說的是但是!U矍贰贝或!
這根本沒有跳轉(zhuǎn)頁面!還是在同一個頁面進(jìn)行操作的锐秦!如果我把大哥的代碼改成:
在我測試的時候咪奖,發(fā)生了奇怪的事情,同樣的代碼酱床,有時候能跑有時候拋出錯誤羊赵,我已設(shè)定休眠時間,難道是我頻繁訪問導(dǎo)致百度封我扇谣?剛才上述的代碼我都實際測試過的昧捷,但是現(xiàn)在又不能用了--wtf--,所以罐寨。我換了穩(wěn)定的引擎靡挥,我采用bing搜索來試試,上面的全部作廢鸯绿,如果有人知道問題出在哪跋破,請留言


等待...

7.19補(bǔ)充

應(yīng)該是搜索引擎熱點的問題,每次鍵入相同的值可能搜索結(jié)果首項會不一致的瓶蝴,百度可能更新熱點比較快把幔烛,所以出現(xiàn)了我所謂不穩(wěn)定的情況


正題測試

這里寫圖片描述

我和上述那位大哥不同的觀點在于,他用的

sreach_window=browser.current_window_handle 

方法并不能實現(xiàn)對新窗口句柄的捕捉囊蓝,我以bing主頁為測試頁饿悬,重新構(gòu)造了一下,

#coding=utf-8
from selenium import webdriver
import time

browser=webdriver.Firefox()
browser.get("http://cn.bing.com/")
keywords = 'MrLevo520 CSDN'
send_keywords=keywords.decode('utf-8')#中英混輸入可防止亂碼
browser.find_element_by_id("sb_form_q").send_keys(send_keywords)

time.sleep(1)
#----------操作一:進(jìn)行對關(guān)鍵字MrLevo520 CSDN搜索----------------
browser.find_element_by_id("sb_form_go").click()#執(zhí)行此操作會進(jìn)行搜索聚霜,但是沒有彈出新窗口狡恬,所以句柄不用重定位
time.sleep(3)
#----------操作二:對搜索頁面"我的CSDN"進(jìn)行點擊操作--------------
browser.find_element_by_xpath("/html/body/div/ol/li/h2/a").click()#進(jìn)行當(dāng)前頁面點擊第一項

#--------操作三:對新彈出的頁面再點擊"貢獻(xiàn)的資源"選項-----
sreach_window=browser.current_window_handle
browser.find_element_by_xpath("/html/body/div[3]/div[2]/div[2]/div/a[3]").click()

time.sleep(5)

瀏覽器運行結(jié)果只到如圖:


并沒有我期待的點擊’貢獻(xiàn)的資源‘

而且拋出錯誤:

selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"xpath","selector":"/html/body/div[3]/div[2]/div[2]/div/a[3]"}

可見珠叔,此語句并沒有實現(xiàn)句柄重定位的功能,然后我再試試下面的方法弟劲,所有語句不變祷安,只改變獲取當(dāng)前句柄的語句,改成

browser.switch_to_window(browser.window_handles[1])

最后程序應(yīng)該是這樣:

#coding=utf-8
from selenium import webdriver
import time

browser=webdriver.Firefox()
browser.get("http://cn.bing.com/")
keywords = 'MrLevo520 CSDN'
send_keywords=keywords.decode('utf-8')#中英混輸入可防止亂碼
browser.find_element_by_id("sb_form_q").send_keys(send_keywords)

time.sleep(1)
#----------操作一:進(jìn)行對關(guān)鍵字MrLevo520 CSDN搜索----------------
browser.find_element_by_id("sb_form_go").click()#執(zhí)行此操作會進(jìn)行搜索兔乞,但是沒有彈出新窗口汇鞭,所以句柄不用重定位
time.sleep(3)
#----------操作二:對搜索頁面"我的CSDN"進(jìn)行點擊操作--------------
browser.find_element_by_xpath("/html/body/div/ol/li/h2/a").click()#進(jìn)行當(dāng)前頁面點擊第一項

#--------操作三:對新彈出的頁面再點擊"貢獻(xiàn)的資源"選項-----
browser.switch_to_window(browser.window_handles[1])
browser.find_element_by_xpath("/html/body/div[3]/div[2]/div[2]/div/a[3]").click()

time.sleep(5)

最后結(jié)果,按照我的思路庸追,進(jìn)行了相應(yīng)的點擊霍骄,最后如圖

達(dá)到目的

所以從上述的例子上來說,語句sreach_window=browser.current_window_handle并沒有實現(xiàn)重定位淡溯,可能我才疏學(xué)淺读整,但至少,在上述的那位大哥的博客中咱娶,寫的是錯誤的米间,運行失敗,我對2016.7.16的所有數(shù)據(jù)負(fù)責(zé)膘侮,實際測試失敗屈糊。



7.17-補(bǔ)充:另一種獲取句柄方法

還有另一種方法,就是直接定位當(dāng)前最新彈出的窗口琼了。代碼是這樣的

for handle in browser.window_handles:#方法二另玖,始終獲得當(dāng)前最后的窗口,所以多要多次使用
    browser.switch_to_window(handle)

那么結(jié)合到我的代碼中那就是這樣的:

#Author:哈士奇說喵
#因為搜索引擎檢索項根據(jù)熱度來排名表伦,所以我只能對7.17的數(shù)據(jù)進(jìn)行測試和負(fù)責(zé),大家測試時候注意元素變化
#coding=utf-8
from selenium import webdriver
import time

browser=webdriver.Firefox()
browser.get("http://cn.bing.com/")
keywords = 'MrLevo520 CSDN'
send_keywords=keywords.decode('utf-8')#中英混輸入可防止亂碼
browser.find_element_by_id("sb_form_q").send_keys(send_keywords)

time.sleep(1)
#----------操作一:進(jìn)行對關(guān)鍵字MrLevo520 CSDN搜索----------------
browser.find_element_by_id("sb_form_go").click()#執(zhí)行此操作會進(jìn)行搜索慷丽,但是沒有彈出新窗口蹦哼,所以句柄不用重定位
time.sleep(3)
#----------操作二:對搜索頁面第一項進(jìn)行點擊操作--------------
browser.find_element_by_xpath("/html/body/div/ol/li/h2/a").click()#進(jìn)行當(dāng)前頁面點擊第一項

#--------操作三:對新彈出的頁面再點擊"我的頭像"選項-----
#注意此時已經(jīng)是彈出的第一個窗口了,需要重新定位句柄
'''browser.switch_to_window(browser.window_handles[1])#方法一'''
for handle in browser.window_handles:#方法二要糊,始終獲得當(dāng)前最后的窗口
    browser.switch_to_window(handle)

browser.find_element_by_xpath("http://div[@id='body']/div[2]/div/div/ul[2]/div/a").click()

#------------------操作四:點擊"貢獻(xiàn)的資源"-------------------
#注意此時已經(jīng)是新彈出的第二個窗口了纲熏,需要重新定位句柄
browser.switch_to_window(browser.window_handles[2])#方法一,注意window_handles[2]變成了2
'''for handle in browser.window_handles:#方法二锄俄,始終獲得當(dāng)前最后的窗口
    browser.switch_to_window(handle)'''

browser.find_element_by_xpath("/html/body/div[3]/div[2]/div[2]/div/a[3]").click()

time.sleep(5)

上面的代碼局劲,我要說幾點,總共實現(xiàn)完成會存在三個瀏覽器窗口奶赠,也就是相當(dāng)于實現(xiàn)了兩次句柄重定位功能鱼填,也就是下面的圖片,對bing搜索“MrLevo520 CSDN”跳出的最熱項毅戈,也就是這一篇(感謝大家厚愛)苹丸,但是昨天最熱彈出來的是直接是我的主頁愤惰,大家從上面的動圖應(yīng)該也可以看出來,所以等你測試這段代碼的時候赘理,可能最熱項目又變化了宦言,道理大家懂就ok,不影響重抓句柄代碼商模。

實現(xiàn)步驟

代碼實現(xiàn)了從1奠旺,到2,點擊頭像后施流,再跳轉(zhuǎn)到3主頁响疚,之后再點擊"貢獻(xiàn)資源",實現(xiàn)的動圖如下:

實現(xiàn)動圖

Pay Attention

1.搜索引擎根據(jù)熱度來排名嫂沉,也就是代碼具有"不穩(wěn)定性"稽寒,應(yīng)該根據(jù)自己實際情況,定位不同元素趟章,我只對當(dāng)前編輯時間的數(shù)據(jù)負(fù)責(zé)

2.在實際操作過程中杏糙,會產(chǎn)生第一個頁面還沒等第二個頁面緩沖完,直接又"占領(lǐng)"主視覺的問題蚓土,別擔(dān)心宏侍,句柄還是在傳遞的,程序一直在跑蜀漆,而且沒有出錯谅河,過一會時間就會更新加載頁面的,如果想要關(guān)閉無關(guān)頁面确丢,請看這篇博客 基于Selenium一鍵寫CSDN博客

3.可能我的代碼第一次獲取句柄和第二次獲取句柄不一樣的方法绷耍,這是為了展示,你可以兩次句柄獲取都用方法二鲜侥,也可以都是用方法一褂始,但是方法一注意修改標(biāo)號。


方法一 VS 方法二

相比較于方法二描函,方法一的優(yōu)點在于后續(xù)操作崎苗,比如關(guān)閉第幾個窗口,句柄傳遞是按照順序來的舀寓。缺點在于對于較多新頁面胆数,有時候彈出窗口太多會變得難以計算。

而方法二互墓,一直在獲取最后的窗口必尼,如果你只是對最后的窗口進(jìn)行操作,也就是(自己定義的)”前向“操作時篡撵,不計后果胰伍,可以直接拿來用齿诞,而且代碼不變。缺點在于骂租,如果要返回到某個窗口句柄祷杈,那就顯得沒有方法一來的好,至少我現(xiàn)在是這么認(rèn)為的渗饮,可能以后我會回來修改但汞。



總結(jié)

我姑且認(rèn)為這句語句,單獨作用于上述博客中是不可行的互站。
所以我在后續(xù)的博客中對窗口重定向語句改成了browser.switch_to_window(browser.window_handles[1])私蕾,至少在我的實驗中,這句語句實現(xiàn)了我需要的操作胡桃。
最后上張動圖表示流程:

過程展示


最后

將待解決實際問題解決踩叭,方法總是好多種,就看自己想不想解決翠胰。

so 容贝,see you guys,have a good night之景!


致謝

@一朵菊花向陽開--python + selenium webdriver 從主窗口A跳轉(zhuǎn)至主窗口B后斤富,無法定位窗口B的元素的問題
@Do it Yourself--python+selenuim webdriver 頁面跳轉(zhuǎn)后如何定位元素
@崔慶才--Python爬蟲利器五之Selenium的用法


原文鏈接

解決Selenium彈出新頁面無法定位元素問題(Unable to locate element)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市锻狗,隨后出現(xiàn)的幾起案子满力,更是在濱河造成了極大的恐慌,老刑警劉巖轻纪,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件油额,死亡現(xiàn)場離奇詭異,居然都是意外死亡刻帚,警方通過查閱死者的電腦和手機(jī)潦嘶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來我擂,“玉大人,你說我怎么就攤上這事缓艳⌒DΓ” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵阶淘,是天一觀的道長衙吩。 經(jīng)常有香客問我,道長溪窒,這世上最難降的妖魔是什么坤塞? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任冯勉,我火速辦了婚禮,結(jié)果婚禮上摹芙,老公的妹妹穿的比我還像新娘灼狰。我一直安慰自己,他們只是感情好浮禾,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布交胚。 她就那樣靜靜地躺著,像睡著了一般盈电。 火紅的嫁衣襯著肌膚如雪蝴簇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天匆帚,我揣著相機(jī)與錄音熬词,去河邊找鬼。 笑死吸重,一個胖子當(dāng)著我的面吹牛互拾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晤锹,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼摩幔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鞭铆?” 一聲冷哼從身側(cè)響起或衡,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎车遂,沒想到半個月后封断,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡舶担,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年坡疼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衣陶。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡柄瑰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出剪况,到底是詐尸還是另有隱情教沾,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布译断,位于F島的核電站授翻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜堪唐,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一巡语、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧淮菠,春花似錦男公、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至曙寡,卻和暖如春糠爬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背举庶。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工执隧, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人户侥。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓镀琉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蕊唐。 傳聞我的和親對象是個殘疾皇子屋摔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容