1 簡介以及安裝
Selenium 是什麼?一句話,自動化測試工具。它支援各種瀏覽器,包括 Chrome,Safari,Firefox 等主流介面式瀏覽器,如果你在這些瀏覽器裡面安裝一個 Selenium 的外掛,那麼便可以方便地實現Web介面的測試。換句話說叫 Selenium 支援這些瀏覽器驅動。Selenium支援多種語言開發,比如 Java,C,Ruby等等,有 Python 嗎?那是必須的!哦這可真是天大的好訊息啊。
Selenium 2,又名 WebDriver,它的主要新功能是整合了 Selenium 1.0 以及 WebDriver(WebDriver 曾經是 Selenium 的競爭對手)。也就是說 Selenium 2 是 Selenium 和 WebDriver 兩個專案的合併,即 Selenium 2 相容 Selenium,它既支援 Selenium API 也支援 WebDriver API。
安裝:如果已經安裝了pip,則可以直接通過它安裝:
pip install selenium
文件: http://selenium-python.readthedocs.io/
2. 簡單使用
2.1 開啟瀏覽器
#!/usr/bin/python from selenium import webdriver browser=webdriver.Firefox() browser.get("http://www.baidu.com")
報錯:
selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable may have wrong permissions.
程式執行錯誤,瀏覽器沒有開啟,那麼應該是沒有把 Firefox 驅動沒有配置在環境變數裡。下載驅動,然後將驅動檔案路徑配置在環境變數即可。
下載地址: https://github.com/mozilla/geckodriver/releases/
下載完成後將其加壓到/usr/local/bin目錄中,然後再在執行,我們看到直接就彈出瀏覽器並且其頁面是百度。
2.2 傳送資料
為了互動方便,就直接用ipython來進行下邊的操作.。(如果沒有,在centos7中可以直接安裝:sudo yum install ipython)。
安裝完成後就可以直接在命令中輸入ipython啟動ipython,然後就可以在其中輸入python語句,並且帶有tab補全功能。下邊示例就是開啟firefox
依次執行以下語:
In [1]: from selenium import webdriver In [2]: from selenium.webdriver.common.keys import Keys # 開啟瀏覽器 In [3]: browser = webdriver.Firefox() # 其中 driver.get 方法會開啟請求的URL,WebDriver 會等待頁面完全載入完成之後才會返回,
# 即程式會等待頁面的所有內容載入完成,JS渲染完畢之後才繼續往下執行。
# 注意:如果這裡用到了特別多的 Ajax 的話,程式可能不知道是否已經完全載入完畢。 In [4]: browser.get("http://www.baidu.com")
然後我們通過firebug(firefox 中按F12),找出百度的輸入框的名稱。發現輸入框的名稱為: wd
接下來,我們通過selenium在這個輸入框中輸入值:
#通過元素名稱找到頁面輸入框 In [5]: elem = browser.find_element_by_name("wd") #在輸入框中輸入查詢內容 In [6]: elem.send_keys("selenium")
這時我們發現在頁面中已經出現了查詢值:
接著可以通過傳送向下箭頭指示讓其在上述的選項中選擇:
elem.send_keys(Keys.ARROW_DOWN)
然後我們可以通過selenium輸入一個回車進行查詢,結果可以直接在瀏覽器中檢視。(是不是感覺很強大,通過語句操作瀏覽器)
In [7]: elem.send_keys(Keys.RETURN)
之後我們可以通過browser.page_source獲得渲染後的頁面
3. 互動
在前邊的2.2部分已經說明一部分關於互動的使用。這裡將更進一步說明。
3.1 元素的獲取(詳情請點這裡: http://selenium-python.readthedocs.io/locating-elements.html)
當有如下定義的元素的時候:
<input type="text" name="passwd" id="passwd-id" />
我們可以通過以下幾種方式定位到這個元素:
# 通過元素ID獲取此元素 element = driver.find_element_by_id("passwd-id") # 通過元素的名稱獲取元素 element = driver.find_element_by_name("passwd") # 通過xpath獲取元素 element = driver.find_element_by_xpath("//input[@id='passwd-id']") # 下邊是其它的方法 find_element_by_tag_name find_element_by_link_text find_element_by_partial_link_text find_element_by_tag_name find_element_by_class_name find_element_by_css_selector
可以通過以下方法找到多個元素:
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
注意:如果沒有找到相應的元素的時候,會丟擲NoSuchElementException
異常。獲取到的元素都用一個類表示,這就意味著,如果你用IDE的時候,給你自動提示很多的方法中不是每一個都能呼叫的。
XPath 是一門在 XML 文件中查詢資訊的語言。XPath 可用來在 XML 文件中對元素和屬性進行遍歷,也可以在HTML中使用,xpath的知識點不多,如果要學習,請點選下邊的地址:
3.2 選擇
前邊我們已經成功獲取並進入到文字框中,現在我們來操作以下其它的元素。比如我們要出發下拉框,我們可以這樣做:
# 獲取下拉的元素 element = driver.find_element_by_xpath("//select[@name='name']") # 獲取下拉中的所有選項 all_options = element.find_elements_by_tag_name("option") # 便利所有的選項,輸出其值,並點選每一個選項 for option in all_options: print("Value is: %s" % option.get_attribute("value")) option.click()
當然上述不是最有效的方式,selenium提供一個類用於處理這種Slelect元素。以下方法可以憑藉其方法名理解其有何用。也可以藉助ipython中的help()來檢視某個方法的作用以及其詳細使用方法。
from selenium.webdriver.support.ui import Select select = Select(driver.find_element_by_name('name')) select.select_by_index(index) select.select_by_visible_text("text") select.select_by_value(value)
試想以下,我們可能拿selenium來做測試,可能需要對所有的選項都要測試,下邊就可以獲取素有的選項:
select = Select(driver.find_element_by_xpath("xpath")) all_selected_options = select.all_selected_options
3.3 提交
當你填寫完成form表單之後,你會通過submit來提交表單。其中的一種方法是通過找到submit按鈕,然後讓你響應點選。
# 假設你的submit的id為ok driver.find_element_by_id("ok").click()
selenium提供了一個方便的submit()方法,當你通過表單元素呼叫submit()方法的時候就可以完成提交。
element.submit()
3.4 拖拽
你可以移動某個元素一定的距離,也可以將一個元素移動到另一個元素中去。
from selenium.webdriver import ActionChains element = driver.find_element_by_name("source") target = driver.find_element_by_name("target") action_chains = ActionChains(driver) action_chains.drag_and_drop(element, target).perform()
3.5 歷史記錄
在歷史記錄中前進或者後退
# 前進到前邊的頁面 driver.forward() # 後退到以前的一個頁面 driver.back()
3.6 Cookies
可以通過以下方法來獲取Cookies
# Go to the correct domain driver.get("http://www.example.com")# And now output all the available cookies for the current URL driver.get_cookies()
4. 等待
這是非常重要的一部分,現在的網頁越來越多采用了 Ajax 技術,這樣程式便不能確定何時某個元素完全載入出來了。這會讓元素定位困難而且會提高產生 ElementNotVisibleException 的概率。
所以 Selenium 提供了兩種等待方式,一種是隱式等待,一種是顯式等待。
顯式等待是指定某一條件直到這個條件成立時繼續執行,隱式等待是等待特定的時間。
顯式等待:
顯示等待是設定一個時間段和一個條件,當超過這個時間段而設定的條件沒有發生則會丟擲異常,只有在規定的時間段內條件發生才算正常
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox() driver.get("http://somedomain/url_that_delays_loading") try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) ) finally: driver.quit()
上訴例子說明在10秒時間內還沒有發現ID為myDynamicElement的元素,則會丟擲TimeoutException異常。實際上會每過500ms去執行條件,當發現了元素後就正確返回。
下邊是可能用到的條件:
title_is title_contains presence_of_element_located visibility_of_element_located visibility_of presence_of_all_elements_located text_to_be_present_in_element text_to_be_present_in_element_value frame_to_be_available_and_switch_to_it invisibility_of_element_located element_to_be_clickable - it is Displayed and Enabled. staleness_of element_to_be_selected element_located_to_be_selected element_selection_state_to_be element_located_selection_state_to_be alert_is_present
隱藏等待:
當需要的元素當前不存在的時候需要等待多長時間。預設的設定時間為0。如果設定了隱式等待,則其在整個WebDriver的例項生存週期類有效。
from selenium import webdriver driver = webdriver.Firefox() driver.implicitly_wait(10) # seconds driver.get("http://somedomain/url_that_delays_loading") myDynamicElement = driver.find_element_by_id("myDynamicElement")