女友由於工作上的失誤,將公司RDM中的某一字段的2000條數據給刪除了.....就算是重新添加字段,但是與其他數據的關聯性已經不在了。由於每天的數據修改量大,有關部門不願意恢復數據庫,因此只能一條條的手動添加啦。我看了下添加流程,估計了修改一條信息至少需要30s,那么2000條數據所需要的時間.....數據還在不停的變動,每天上班還有其他事情。身為程序猿的我,只好拿出自動化終極工具Selenium來拯救她了!
一. 元素定位問題
一些基本的元素定位方法,官方文檔上面已經有詳細的說明了。這里就不啰嗦了,我一般是使用的XPATH
定位,寫一下我遇到的一些問題。
使用find_element_by_xxx('div')其實都是調用find_element(By.xxx,'div')
以XPATH
為例,css
,id
,class
等都是同理
##這是源代碼中對find_element_by_xpath的定義
def find_element_by_xpath(self, xpath):
"""
Finds an element by xpath.
:Args:
- xpath - The xpath locator of the element to find.
:Usage:
driver.find_element_by_xpath('//div/td[1]')
"""
return self.find_element(by=By.XPATH, value=xpath)
browser.find_element_by_xpath('//div[@id="home"]/span')
##等價於
browser.find_element(By.XPATH, '//div[@id="home"]/span')
**注: **如果你是想查找某個元素列表的話,例如
ul
下的所有li
,記得是使用find_elements
,而不是find_element
.
**注: **如果你想查找ul
下的li
中符合某一標准的那個li
。例如,你想查找所有li
中內容為海賊王
的那個li
:
li = browser.find_element_by_xpath("//ul/li[contains(text(),'海賊王')]")
另外:有時,你需要定位的元素在頁面上需要滾動幾下才能顯示。在我的實踐中,這種情況不需要加滾動事件,直接可以通過xpath定位后click()
。比如下拉框菜單內容很多的時候,點擊下拉框,讓下拉菜單顯示出來之后,就可以直接定位到所有菜單選項。
二. 使用WebElement.text獲取內容問題
文檔中的說明:
People often wish to retrieve the innerText value contained within an element. This returns a single string value. Note that this will only return the visible text displayed on the page.
用text獲取值,只能獲取到當時在頁面上能顯示出來的值。比如下拉框,想要獲取下拉框里面選項的值,需要點擊下拉框,將下拉菜單顯示出來之后再獲取,不然獲取的都是空值。
三. iframe問題
iframe
中的元素不能直接的定位,需要使用browser.switch_to.frame("frameId")
先切換到iframe下,然后定位。
##iframe是內嵌關系,需要到最里層的createFrame中去
browser.switch_to.frame('main')
browser.switch_to.frame('undefined_frame')
browser.switch_to.frame('createFrame')
如果你將這種代碼放入到了循環中,記得要在每一個循環開始或結束后加上browser.switch_to.default_content()
還原到頂層html
for i in range(10):
browser.switch_to.default_content()
browser.switch_to.frame('main')
browser.switch_to.frame('undefined_frame')
browser.switch_to.frame('createFrame')
##
# 定位createFrame中的元素
# ...
###
四. ElementNotVisibleException等異常
好多次碰到這種異常,還有can not clickable這種異常,明明是存在的元素,在循環運行時突然就來了這么個異常,原因估計是因為瀏覽器的速度跟不上程序運行的速度,導致程序已經開始搜索某個元素時,瀏覽器還沒有解析完成,就會導致各種異常,使用time.sleep(2)
來休眠一下一般都可以解決問題,但是使用browser.implicitly_wait(2)好像不行。