Python爬蟲學習(9):Selenium的使用

1 簡介以及安裝css

  Selenium 是什麼?一句話,自動化測試工具。它支持各類瀏覽器,包括 Chrome,Safari,Firefox 等主流界面式瀏覽器,若是你在這些瀏覽器裏面安裝一個 Selenium 的插件,那麼即可以方便地實現Web界面的測試。換句話說叫 Selenium 支持這些瀏覽器驅動。Selenium支持多種語言開發,好比 Java,C,Ruby等等,有 Python 嗎?那是必須的!哦這可真是天大的好消息啊。html

  Selenium 2,又名 WebDriver,它的主要新功能是集成了 Selenium 1.0 以及 WebDriver(WebDriver 曾經是 Selenium 的競爭對手)。也就是說 Selenium 2 是 Selenium 和 WebDriver 兩個項目的合併,即 Selenium 2 兼容 Selenium,它既支持 Selenium API 也支持 WebDriver API。python

  安裝:若是已經安裝了pip,則能夠直接經過它安裝:git

 pip install selenium

  文檔: http://selenium-python.readthedocs.io/github

2. 簡單使用web

  2.1 打開瀏覽器centos

#!/usr/bin/python

from selenium import webdriver

browser=webdriver.Firefox()
browser.get("http://www.baidu.com")

  報錯:api

selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable may have wrong permissions. 

  程序執行錯誤,瀏覽器沒有打開,那麼應該是沒有把 Firefox 驅動沒有配置在環境變量裏。下載驅動,而後將驅動文件路徑配置在環境變量便可。瀏覽器

  下載地址: https://github.com/mozilla/geckodriver/releases/cookie

  下載完成後將其加壓到/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的知識點很少,若是要學習,請點擊下邊的地址:

  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")

 

 

    API 地址

相關文章
相關標籤/搜索