Selenium 實例講解網(wǎng)站登錄及元素定位方法總結(jié)

本文主要介紹了如何利用Selenium對網(wǎng)站進行登錄,Xpath元素定位,及窗口操作的一些常用方法,附上詳細代碼及解析,同時簡單總結(jié)元素定位不到的原因有哪些。雙擊下面圖片查看動圖

雙擊圖片,查看效果


一 圖片驗證碼登錄

這部分主要完成瀏覽器打開,通過元素定位在瀏覽器中輸入賬號、密碼信息,最后通過OCR識別技術(shù)完成驗證碼的輸入,保證登錄成功。

1.1啟用瀏覽器并打開測試網(wǎng)站

代碼:


From selenium import webdriver #將webdriver驅(qū)動導(dǎo)入selenium框架中

from pip._vendor.requests.cookies import get_cookie_header

#導(dǎo)入cookie(獲取cookie時使用)

import time#導(dǎo)入時間包(后續(xù)time函數(shù)使用)

#將chrome驅(qū)動地址賦值給chromdriver

browser=webdriver.Firefox()#打開Firefox瀏覽器

browser.get("https://login.xxxx.com/en?dest_url=https://xxxx.com/en/contact")

#打開測試網(wǎng)站(此網(wǎng)站地址需要填寫自己測試的網(wǎng)站地址)

1.2設(shè)置等待時間


在上面登錄過程中網(wǎng)頁加載慢,出現(xiàn)了還沒等圖片完全加載出來就進行圖片識別的現(xiàn)象,導(dǎo)致識別失敗,如下圖

那么我們應(yīng)該如何操作去避免提前加載的現(xiàn)象呢?

如果給它加一個條件滿足(圖片驗證碼顯示完全)時:再進行圖片識別操作是否可行呢,我們來看看

Selenium有3種等待時間:

名稱 方法 特點

強制等待 Thread.sleep() 執(zhí)行到此時不管什么就固定的等待三秒之后再接著執(zhí)行后面的操作

隱式等待方法 implicitlyWait() 隱式等待采用全部設(shè)置,此方法針對執(zhí)行腳本的所有對象,等待10秒

顯示等待方法 WebDriverWait() 明確的要等到某個元素的出現(xiàn)或者是某個元素的可點擊等條件,等不到,就一直等,除非在規(guī)定的時間之內(nèi)都沒找到,那么就跳出Exception

這里使用WebDriverWait()方法:

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)

driver :瀏覽器驅(qū)動名稱

timeout :最長超時時間,默認以秒為單位。

poll_frequency :檢測的間隔(步長)時間,默認為0.5S。

ignored_exceptions :超時后的異常信息,默認情況下拋NoSuchElementException異常

WebDriverWait()一般由until()或until_not()方法配合使用

HTML結(jié)構(gòu):


代碼:

Element=WebDriverWait(browser,100).until(

? ? EC.presence_of_element_located((By.ID,"captcha_img_id"))

)

代碼意思是:ID名稱為"captcha_img_id"的元素顯示等待100s,如果沒有出現(xiàn),拋出異常,通過上面方法就可以處理等待頁面元素加載完全后進行相關(guān)功能操作。

1.3賬號、密碼元素定位并輸入內(nèi)容


首先通過F12打開代碼界面,點擊元素定位圖標,選中要定位的“賬號”文本框內(nèi)容,在代碼區(qū)域找到定位的元素代碼信息,如下圖中的name名稱“l(fā)ogin”,密碼元素同理

代碼:

browser.find_element_by_name("Login").send_keys("xxxx")

#通過name定位登錄文本框,通過send_keys輸入賬戶信息

browser.find_element_by_name("Password").send_keys("xxxx")

#通過name定位密碼文本框,通過send_keys輸入密碼信息

1.4驗證碼處理-使用OCR自動識別

看網(wǎng)上介紹驗證碼處理大致有4種方法,1.讓開發(fā)把驗證碼代碼注釋掉 2.讓開發(fā)設(shè)置萬能驗證碼 3.通過添加cookie方式繞過圖片驗證碼 4.OCR自動識別,其中1-2因為這個網(wǎng)站與開發(fā)接觸不到,不予考慮方法3一般適用于記住登錄狀態(tài)的網(wǎng)站才適合,這里我使用第4種方法,這種方法適合于處理比較簡單的驗證碼

OCR自動識別的原理是什么呢?

在這里我們需要使用pytesseract,它是一款用于光學(xué)字符識別(OCR)的python工具,即從圖片中識別出其中嵌入的文字。整個過程分為截取登錄頁面->獲取驗證碼的位置坐標->打開截圖->從截圖中截取驗證碼的區(qū)域->使用pytesseract工具識別驗證碼

代碼:

browser.save_screenshot('f://a.png')#截取當(dāng)前網(wǎng)頁,該網(wǎng)頁有我們需要的驗證碼

yzm=browser.find_element_by_id("captcha_img_id") #定位驗證碼

location=yzm.location#獲取驗證碼x,y軸坐標

size=yzm.size#獲取驗證碼的長寬

rangle=(int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height']))#截取的位置坐標

i=Image.open("f://a.png") #打開截圖

frame4=i.crop(rangle) #使用Image的crop函數(shù),從截圖中再次截取我們需要的區(qū)域

frame4.save('f://frame4.jpg')#將截取到的驗證碼保存為jpg圖片

qq=Image.open('f://frame4.jpg')#打開jpg驗證碼圖片

text=pytesseract.image_to_string(qq).strip() #使用image_to_string識別驗證碼

browser.find_element_by_name("turing").send_keys(text)#將識別的圖片驗證碼信息輸入到驗證碼輸入文本框中

browser.find_element_by_class_name("btn").click()#點擊登錄按鈕

運行代碼后可能會遇到提示“系統(tǒng)找不到指定文件”


這個問題困擾了我好久,最后處理方案如下:

首先保證pytesseract環(huán)境安裝正確-參見pytesseract環(huán)境安裝文章:

https://www.cnblogs.com/hupeng1234/p/7136442.html

其次,打開文件 pytesseract.py,找到如下代碼,將tesseract_cmd的值修改為全路徑如:

tesseract_cmd = 'C:\\Program Files\\Tesseract-OCR\\tesseract'#這里一定要用\\不能用\,在程序里\\表示轉(zhuǎn)譯,如果只使用\是沒用的。

運行代碼,圖1中的整個自動登錄功能就實現(xiàn)了,怎么樣有沒有一種要飛的感覺…

二Firepath工具方法定位元素

2.1 實現(xiàn)的主要功能

點擊用戶名稱,選擇選中下拉菜單選項進入詳細頁面

借助Firebug和Firepath工具,方便我們使用Xpath對元素進行定位,這里我們使用Xpath定位,一般都通過Xpath結(jié)合屬性值進行定位元素,95%以上的定位都能通過此方法解決

2.2具體操作

1. 首先下載Firebug和Firepath工具,下載步驟:工具-web開發(fā)者-獲取更多工具-搜索框搜索Firebug-添加到Firefox即可【Firepath同理】


2. 工具使用,firefox中按[F12]

(1) 在Firebug 選項左鍵單擊

(2) 右鍵選中要定位的元素選擇【使用Firebug查找元素】

(3) 右鍵選中高亮代碼,右鍵選擇在FirePath面板中查看

(4) FirePath下文本框內(nèi)容就是Xpath定位命令,拷貝命定到代碼編輯器中(elipse)

HTML代碼:



3. 定位Xpath元素,實現(xiàn)點擊按鈕

browser.find_element_by_xpath("http://*[@id='navbar']/ul[2]/li[1]/a").click()

其中“//*[@id='navbar']/ul[2]/li[1]/a”這句話表示什么意思呢,跟著我一步一步看,(1)//表示在文檔的全部層級進行查找

(2)[@id='navbar']表示定位id='navbar'元素下

(3)ul[2]表示定位到第二個無序列表的樣式ul下

(4)li[1]表示定位到第一個列表內(nèi)行的樣式li下

(5)a表示定位到超鏈接下

從(1)到(5)是逐級展開的

4. 通過link text定位元素實現(xiàn)跳轉(zhuǎn)


實現(xiàn)代碼:browser.find_element_by_link_text("Discover").click()

(1) by_link_text:文本鏈接方式

(2) click():鼠標點擊功能

Firepath工具可以幫助我們輕松定位元素,對于初學(xué)者是一個非常不錯的工具,熟練之后再慢慢練習(xí)自己寫。

三.元素定位不到原因分析--窗口句柄


在程序運行過程中,一直提示元素定位不到“unable to locate element”,這個問題我解決了大概有一個星期,下面是我的解決思路。

頁面元素結(jié)構(gòu):

定位代碼:

browser.find_element_by_xpath("http://form/div/div/descendant::a[@href='/adview']").click()

1. 無論怎么定位都提示“unable to locate element”,如下圖


于是就開啟了找問題出在哪里

3.1.網(wǎng)上查定位元素不到的原因有哪些

首先,我在網(wǎng)上查元素定位不到的原因,因為根據(jù)提示,我們知道是元素沒有定位成功

網(wǎng)上的思路大概都是:

1. 定位的ID是動態(tài),這里不涉及ID,所以排除

2. iframe原因定位不到元素

3. 不在同一個frame里邊查找元素,這里不涉及iframe元素,所以2/3排除

4. Xpath描述錯誤

剛開始我以為是我元素定位的錯誤,所以花了很多時間在換各種方式進行定位:包括使用Selenium IDE 工具、使用Link()方法、利用Firepath 中的Xpath Css定位,仍提示定位不成功

5. 點擊速度過快 頁面沒有加載出來就需要點擊頁面上的元素

我在語句前面加上加載時間time.sleep(5)等待,還是不行

6. firefox安全性強,不允許跨域調(diào)用出現(xiàn)報錯

錯誤描述:uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMNSHTMLDocument.execCommand]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location:

根據(jù)錯誤描述,這點也不符合,排除

3.2. 如何排除不是語句錯誤

根據(jù)之前操作,感覺不應(yīng)該定位語句錯誤的原因,所以如何排除判斷是不是語句錯誤呢

1. 因為這個頁面屬于登錄成功后調(diào)用的第二個頁面,所以我從上一頁面開始,把之前的代碼前加上注釋#后運行

2.結(jié)果調(diào)用成功了,直接跳轉(zhuǎn)到第三個頁面了,可以說明語句沒有編寫錯誤

3.這里還有一個方法,就是你換其他瀏覽器試一試,但是我覺得還得重新配置太麻煩了

3.3 罪魁禍首-窗口句柄

既然語句編寫的沒有問題,那么我又開始懷疑人生了,到低哪里出錯了

1. 繼續(xù)網(wǎng)上找資料,發(fā)現(xiàn)是從a頁面到b頁面,窗口句柄還停留在上一個頁面,所以無法定位元素

窗口句柄是什么

想要在某個窗口做一些事情,你就得讓操作系統(tǒng)知道你是在哪一個窗口做這些事情,而窗口的句柄就能起到識別哪一個窗口的作用

所以剛剛進入到一個頁面后,將窗口進行重新定位應(yīng)該就可以了

time.sleep(5

browser.switch_to_window(browser.window_handles[1])

browser.find_element_by_xpath("http://form/div/div/descendant::a[@href='/adview']").click()

總結(jié):以后再遇到跳轉(zhuǎn)新頁面的時候不要忘記加窗口句柄?。?!

本篇文章就到這里,附上所有運行代碼:

# coding=gbk

'''

Created on 2018年3月8日

@author: Administrator

'''

#!/usr/bin/python

# -*-encoding:utf-8 -*-

#1.啟用瀏覽器并打開測試網(wǎng)站

from PIL import Image

import pytesseract

from selenium import webdriver #將webdriver驅(qū)動導(dǎo)入selenium框架中

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from pip._vendor.requests.cookies import get_cookie_header#導(dǎo)入cookie

import time#導(dǎo)入時間包

from pydoc import browse

from pip import locations

from test.test_largefile import size

from _elementtree import Element

from select import select

from cgitb import text

from test.test_os import LoginTests

#chromedriver="C:\Program Files\Internet Explorer\IEDriverServer.exe"#將chrome驅(qū)動地址賦值給chromdriver

#browser=webdriver.Chrome()

browser=webdriver.Firefox()

browser.get("https://login.acesse.com/en?dest_url=https://acesse.com/en/contact")#打開測試網(wǎng)站?

Element=WebDriverWait(browser,100).until(

? ? EC.presence_of_element_located((By.ID,"captcha_img_id"))

? ? )

#2.對賬號、密碼元素進行定位

browser.find_element_by_name("Login").send_keys("xxxxx")

browser.find_element_by_name("Password").send_keys("xxxxxxx")

#3.驗證碼處理-使用OCR自動識別

#browser.maximize_window()

def login():

? ? browser.save_screenshot('f://a.png')#截取當(dāng)前網(wǎng)頁,該網(wǎng)頁有我們需要的驗證碼

? ? yzm=browser.find_element_by_id("captcha_img_id") #定位驗證碼

? ? location=yzm.location#獲取驗證碼x,y軸坐標

? ? size=yzm.size#獲取驗證碼的長寬

rangle=(int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height']))#截取的位置坐標

? ? i=Image.open("f://a.png") #打開截圖

? ? frame4=i.crop(rangle) #使用Image的crop函數(shù),從截圖中再次截取我們需要的區(qū)域

? ? frame4= frame4.convert('RGB')

? ? frame4.save('f://frame4.jpeg')#講截取到的驗證碼保存為jpg圖片

? ? qq=Image.open('f://frame4.jpeg')#打開jpg驗證碼圖片

? ? text=pytesseract.image_to_string(qq).strip() #使用image_to_string識別驗證碼

? ? browser.find_element_by_name('turing').send_keys(text)#將識別的圖片驗證碼信息輸入到驗證碼輸入文本框中

? ? browser.find_element_by_class_name("btn").click()#點擊登錄按鈕

login()

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

browser.find_element_by_xpath('/html/body/div[1]/nav/div/div[3]/ul[2]/li[2]/ul/li[6]/a/span').click()

#browser.implicitly_wait(30)

time.sleep(5)

browser.switch_to_window(browser.window_handles[1])

browser.find_element_by_xpath("http://form/div/div/descendant::a[@href='/adview']").click()

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容