python3 web測試模塊selenium

selenium是一個用於web應用程序測試工具,selenium測試直接運行在瀏覽器中,就像真正的用戶在操做同樣,支持的瀏覽器包括IE(7,8,9,10,11),mozilla firefox,safari,google chrom,opera等,可以使用java,python等多種語言編寫用例腳本。css

Selenium Python綁定提供了一個簡單的API,可使用Selenium WebDriver編寫功能/驗收測試。經過Selenium Python API,您能夠直觀地訪問Selenium WebDriver的全部功能。html

Selenium Python綁定提供了一個方便的API來訪問Selenium WebDrivers,如Firefox,Ie,Chrome,Remote等。目前支持的Python版本是2.7,3.5及更高版本java

一、selenium安裝配置

pip安裝:python

pip install selenium

wheel安裝:linux

#下載wheel安裝文件:https://pypi.python.org/pypi/selenium/#downloads
pip install selenium-3.13.0-py2.py3-none-any.whl

chrome瀏覽器支持的chromeDriver驅動配置:git

注意:此前必須安裝好chrome瀏覽器github

chromedriver下載地址:https://sites.google.com/a/chromium.org/chromedriver/downloadsweb

首先查看chrome瀏覽器版本,而後選定支持瀏覽器版本的chromDriver選擇適合的平臺包進行下載,下載完後須要配置環境:mongodb

在windows系統中能夠將chromedriver.exe文件直接拖到python的scripts目錄中便可,也能夠將路徑加入到環境變量中。chrome

在linux下須要將可執行文件配置到環境變量或將文件移動到屬於環境變量的目錄中

驗證安裝是否成功,可執行命令chromedriver,若是能夠看到chromeDriver的版本號說明安裝成功

使用python腳本測試:

from selenium import webdriver

browser=webdriver.Chrome()

#若是能彈出一個空白的chrome瀏覽器頁面,說明配置成功

其餘瀏覽器的驅動安裝配置同樣,附上其餘瀏覽器的驅動下載連接地址:

Firefox:https://github.com/mozilla/geckodriver/releases

safari:https://webkit.org/blog/6900/webdriver-support-in-safari-10/

edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

咱們還可使用phantomJS一個無界面的webkit瀏覽器引擎,它原生支持多種web標準:DOM操做,CSS選擇器,JSON,Canvas以及SVG

下載地址:http://phantomjs.org/download.html

下載完成後,將PhantomJS可執行文件所在的路徑配置到環境變量中,如在windows降低下載的文件解壓以後打開會看到一個bin文件夾,裏面包含一個可執行文件phantomjs.exe,咱們須要將它直接放在配置好的環境變量路徑下或者將它所在的路徑配置到環境變量裏,或直接將它複製到python的scripts文件夾下

測試安裝:

(virtualenv-36) C:\Users\Administrator\PycharmProjects\untitled\pachong>phantomjs -v
2.1.1
#在python的terminal環境下執行命令phantomjs -v,若是能打印版本信息說明安裝成功

Selenium支持PhantomJS,不過phantomJS官方說明已再也不更新了,在selenium中使用phantomJS將彈出警告信息,建議使用chrome或firefox無頭版,下面將重點介紹chrome和firefox

二、Selenium的基本使用

(1)聲明瀏覽器對象

Selenium支持不少瀏覽器包括chrome、Firefox、Edge、Safari等,各瀏覽器初始化對象方法:

from selenium import webdriver

#browser=webdriver.Firefox()
browser=webdriver.Chrome()
#browser=webdriver.Edge()
#browser=webdriver.Safari()

print(type(browser))

#返回的是一個WebDriver對象
<class 'selenium.webdriver.chrome.webdriver.WebDriver'>

WebDriver對象的方法和屬性:(獲取節點方法在後續介紹)

  • add_cookie(cookie_dict):  爲當前會話添加一個cookie,爲字典類型
  • back():    在瀏覽器歷史記錄中後退一步
  • forward(): 在瀏覽器歷史上前進一步
  • close():    關閉當前窗口
  • create_web_element(element_id):  使用指定的id建立Web元素
  • delete_all_cookies():  刪除會話範圍內的全部cookie
  • delete_cookie(name): 刪除具備給定名稱的單個cookie
  • execute(driver_command,params=None):  發送command執行的命令
  • execute_async_script(script,*args):  異步執行當前窗口或框架中的JavaScript
  • execute_script(script,*args):  同步執行當前窗口或框架中的JavaScript
from selenium import webdriver
driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.execute_script("alert('are you sure');")

#它基本能夠實現JavaScript的全部功能
  • fullscreen_window():調用窗口管理器特定的全屏操做
  • get(url):在當前瀏覽器會話中加載網頁
  • get_cookie(name):按名稱獲取單個cookie
  • get_cookies():返回一組字典的cookies
  • get_log(log_type):獲取給定日誌類型的日誌
  • get_screenshot_as_base64():獲取當前窗口的屏幕截圖,做爲base64編碼的字符串
  • get_screenshot_as_file(filename):將當前窗口中的截屏保存爲png圖形
  • get_screenshot_as_png():獲取當前窗口的屏幕截圖做爲二進制數據
  • get_window_position(windowhandle='current'):獲取當前窗口的x,y位置
  • get_window_rect():獲取窗口的x,y座標以及當前窗口的高度和寬度
  • get_window_size():獲取當前窗口的高度和寬度
  • maximize_window():最大化webdriver正在使用的當前窗口
  • minimize_window():最小化當前webdricer使用窗口
  • quit():退出驅動程序並關閉每一個關聯的窗口
  • refresh():刷新當前頁面
  • save_screenshot(filename):將當前窗口的屏幕截圖保存爲PNG圖形文件
  • set_page_load_timeout(time_to_wait):設置等待頁面加載完成的時間
  • set_script_timeout(time_to_wait):設置腳本在執行期間等待的時間
  • set_window_position(x,y,windowHandle='current'):設置當前窗口的x,y位置
  • set_window_rect(x=None,y=None,width=None,height=None):設置窗口的x,y座標以及當前窗口的高度和寬度
  • set_window_size(width,height,windowHandle='current'):設置當前窗口的高度和寬度
  • current_url:獲取當前頁面的URL
  • current_window_handle:返回當前窗口的句柄
  • desired_capabilities:返回驅動程序當前使用的所需功能
  • log_types:獲取可用日誌類型的列表
  • name:返回此實例的基礎瀏覽器的名稱
  • page_source:獲取當前頁面的源碼
  • switch_to:將焦點切換到全部選項的對象上driver.switch_to.alert
  • title:返回當前頁面的標題
  • window_handles:返回當前會話中全部窗口的句柄
from selenium import webdriver

browser=webdriver.Chrome()
browser.get('http://selenium-python.readthedocs.io')
browser.execute_script('window.open("https://www.baidu.com");')  #在標籤頁打開URL
browser.execute_script('window.open("https://www.taobao.com");')

browser.back()  #後退到前一個頁面
browser.set_page_load_timeout(5)
browser.forward()  #前進到下一個頁面 print(browser.name)
print(browser.title)
print(browser.current_url)
print(browser.current_window_handle)
print(browser.get_cookies())
print(type(browser))

#
chrome
Selenium with Python — Selenium Python Bindings 2 documentation
http://selenium-python.readthedocs.io/
CDwindow-243FD31239F20FCC0195DD522A60A0DA
[{'domain': '.readthedocs.io', 'expiry': 1530766561, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': 'GA1.2.1126774326.1530680157'}, {'domain': '.readthedocs.io', 'expiry': 1593752161, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA1.2.2096958532.1530680157'}, {'domain': '.readthedocs.io', 'expiry': 1530680217, 'httpOnly': False, 'name': '_gat_rtfd', 'path': '/', 'secure': False, 'value': '1'}]
<class 'selenium.webdriver.chrome.webdriver.WebDriver'>

獲取頁面截圖:

from selenium import webdriver

driver=webdriver.Chrome()
driver.get('http://www.python.org')
driver.save_screenshot('screenshot.png')  #保持頁面截圖到當前路徑
driver.quit()

將頁面滾動到底部:

from selenium import webdriver
driver=webdriver.Chrome()
driver.get('http://www.python.org')
#經過DOM中的window對象的scrollTo方法,將窗口位置滾動到指定位置,document.body.scrollHeight返回整個body的高度,因此頁面將滾動到頁面底部
driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")

cookies操做:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/5 16:19
# @Author  : Py.qi
# @File    : test7.py
# @Software: PyCharm
from selenium import webdriver
driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
print(driver.get_cookies())   #獲取全部cookies
driver.add_cookie({'name':'name','domain':'www.baidu.com','value':'germey'})   #添加cookie
print(driver.get_cookies())
driver.delete_all_cookies()
print(driver.get_cookies())

(2)定位元素

class selenium.webdriver.common.by.By
有各類策略來定位頁面中的元素。你可使用最適合你的狀況。Selenium提供瞭如下方法來定位頁面中的元素:

find_element_by_id
find_element_by_name
find_element_by_xpath
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
除了上面給出的公共方法以外,還有兩個私有方法可能對頁面對象中的定位器有用。這些是兩個私有方法:find_element和find_elements

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/4 13:03
# @Author  : Py.qi
# @File    : test2.py
# @Software: PyCharm
from selenium import webdriver
from selenium.webdriver.common.by import By
driver=webdriver.Chrome()
driver.get('http://selenium-python.readthedocs.io/locating-elements.html#locating-elements')
data=driver.find_element(By.CLASS_NAME,'simple')
#driver.find_element(By.ID,'IDname') #獲取ID標籤訂位元素
#driver.find_element(By.CSS_SELECTOR,'cssname')#CSS選擇器定位元素
#driver.find_element(By.LINK_TEXT,'linktext') #連接文本定位元素
#driver.find_element(By.PARTIAL_LINK_TEXT,'linktext') #部分連接文件定位元素
#driver.find_element(By.NAME,'name') #屬性名定位元素
#driver.find_element(By.TAG_NAME,'tagname') #標籤名定位元素

print(data.text)  #打印元素文本內容

#
find_element_by_id
find_element_by_name
find_element_by_xpath
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
#如獲取多個,但是使用:
data=driver.find_elements(By.CLASS_NAME,'simple')

除了使用上面的方法外,還可使用更細緻的方法定位元素:

經過Id定位:
當您知道元素的id屬性時使用此選項。使用此策略,將返回id屬性值與該位置匹配的第一個元素,如使用find_elements_by_id將返回多個匹配的元素。若是沒有元素具備匹配的id 屬性,NoSuchElementException則會引起

driver.find_element_by_id('idname')
driver.find_elements_by_id('idname')

按名稱定位:
當您知道元素的name屬性時,請使用此選項。使用此策略,將返回名稱屬性值與位置匹配的第一個元素,如使用find_elements_by_name將返回多個匹配的元素。若是沒有元素具備匹配的name 屬性,NoSuchElementException則將引起

driver.find_element_by_name('name')
driver.find_elements_by_name('name')

經過XPath定位:
XPath是用於在XML文檔中定位節點的語言。因爲HTML能夠是XML(XHTML)的實現,所以Selenium用戶能夠利用這種強大的語言來定位其Web應用程序中的元素。XPath擴展了經過id或name屬性定位的簡單方法,並打開了各類新的可能性,例如在頁面上查找第三個複選框。

使用XPath的主要緣由之一是當您沒有適合您要查找的元素的id或name屬性時。您可使用XPath以絕對術語或相對於具備id或name屬性的元素來定位元素。XPath定位器也能夠用來經過id和name以外的屬性指定元素。

XPaths包含根(html)中全部元素的位置,所以可能會失敗,只需對應用程序進行最輕微的調整。經過查找具備id或name屬性的附近元素(理想狀況下是父元素),能夠根據關係找到目標元素。這不太可能改變,可使您的測試更加健壯

driver.find_element_by_xpath("//from[1]")  #查看第一個表單元素
friver.dind_element_by_xpath("//from[@id='loginform']")  #查找id爲loinform的表單元素

經過連接文本查找超連接:
當您知道錨標記中使用的連接文本時,請使用此選項。使用此策略,將返回連接文本值與位置匹配的第一個元素。若是沒有元素具備匹配的連接文本屬性,NoSuchElementException則將引起

<HTML>
 <BODY>
  <p>你肯定要這麼作嗎?</ p>
  <a href="continue.html">繼續</a>
  <a href="cancel.html">取消</a>
</ BODY>
<HTML>


driver.find_element_by_link_text('繼續)  #經過連接文本定位到元素

按標籤名稱定位元素:
若是要按標籤名稱查找元素,請使用此選項。使用此策略,將返回具備給定標記名稱的第一個元素。若是沒有元素具備匹配的標記名稱,NoSuchElementException 則將引起

driver.find_element_by_tag_name('h1')

按類名定位元素:
若是要按類屬性名稱定位元素,請使用此選項。使用此策略,將返回具備匹配類屬性名稱的第一個元素。若是沒有元素具備匹配的類屬性名稱,NoSuchElementException則將引起

driver.find_element_by_class_name('content')

經過CSS選擇器定位元素:
當你想經過CSS選擇器語法找到一個元素時使用它。使用此策略,將返回具備匹配的CSS選擇器的第一個元素。若是沒有元素具備匹配的CSS選擇器,NoSuchElementException則會引起

driver.find_element_by_css_selector('p.content')

(3)元素對象(element)

當咱們經過上面 的方法定位到元素後返回的對象稱爲web元素對象,咱們能夠對元素對象再進行交互或繼續查找等操做

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/4 13:55
# @Author  : Py.qi
# @File    : test3.py
# @Software: PyCharm
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
opt=Options()
opt.add_argument('headless')
driver=webdriver.Chrome(chrome_options=opt)
driver.get('http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement')
element=driver.find_element_by_id('module-selenium.webdriver.remote.webelement')
print(element)
print(type(element))

#返回一個webelement對象
<selenium.webdriver.remote.webelement.WebElement (session="dfaee65201abdf5a931306df6e7fe421", element="0.95256057244967-1")>
<class 'selenium.webdriver.remote.webelement.WebElement'>
  • selenium.webdriver.remote.webelement.WebElement爲一個DOM元素,它的方法和屬性包括:
  • clear() :清除文本元素
  • click() :單擊元素按鈕
  • get_attribute(name) :獲取元素的給定屬性的屬性值
  • get_property(name) :獲取元素的給定屬性
  • is_displayed() :判斷元素是否存在
  • is_enable() :判斷元素是否被啓用
  • is_selected() :返回元素是否被選中
  • screenshot(filename) :將當前元素的屏幕截圖保存到文件
  • send_keys() #發送元素值
  • submit() :提交表單
  • value_of_css_property() :CSS屬性的值
  • id :selenium使用的內部ID
  • location :元素在可渲染畫布中的位置
  • location_once_scrolled_into_view :發現元素在屏幕視圖中的位置
  • rect :返回包含元素大小和位置的字典
  • screenshot_as_base64 :獲取當前元素的截屏,做爲base64編碼的字符串
  • size :獲取元素的大小
  • tag_name :獲取元素的tagName屬性
  • text :獲取元素的文本
與頁面交互,實現輸出文本搜索功能,並打印搜索結果源碼:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/4 13:55
# @Author  : Py.qi
# @File    : test3.py
# @Software: PyCharm
from selenium import webdriver

driver=webdriver.Chrome()
driver.get('http://www.cnblogs.com/zhangxinqi/')
element=driver.find_element_by_id('q')  #獲取輸入框元素
element.send_keys('python3之requests')  #發送元素
button=driver.find_element_by_id('btnZzk')  #獲取搜索按鈕
button.click()  #發送搜索動做
data=driver.page_source   

print(driver.current_url)   #打印URL
print(data)
print(type(element))
driver.close()

#
http://zzk-s.cnblogs.com/s?w=blog%3Azhangxinqi%20python3%E4%B9%8Brequests
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>
    <meta charset="utf-8" />
    <title> blog:zhangxinqi python3之requests - 博客園找找看</title>......

(4)動做鏈

class selenium.webdriver.common.action_chains.ActionChains(driver)

 在上面的實例中咱們針對的是某個節點元素的操做,若是要對沒有特定元素的對象操做如鼠標拖拽、鍵盤按鍵等,這些動做就稱爲動做鏈,selenium使用ActionChains()類來實現鼠標移動,鼠標按鈕操做,按鍵操做和上下文菜單交互,懸停和拖放等

  • click(on_element=None) ——單擊鼠標左鍵
  • click_and_hold(on_element=None) ——點擊鼠標左鍵,不鬆開
  • context_click(on_element=None) ——點擊鼠標右鍵
  • double_click(on_element=None) ——雙擊鼠標左鍵
  • drag_and_drop(source, target) ——拖拽到某個元素而後鬆開
  • drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某個座標而後鬆開
  • key_down(value, element=None) ——按下某個鍵盤上的鍵
  • key_up(value, element=None) ——鬆開某個鍵
  • move_by_offset(xoffset, yoffset) ——鼠標從當前位置移動到某個座標
  • move_to_element(to_element) ——鼠標移動到某個元素
  • move_to_element_with_offset(to_element, xoffset, yoffset) ——移動到距某個元素(左上角座標)多少距離的位置
  • perform() ——執行鏈中的全部動做
  • release(on_element=None) ——在某個元素位置鬆開鼠標左鍵
  • send_keys(*keys_to_send) ——發送某個鍵到當前焦點的元素
  • send_keys_to_element(element, *keys_to_send) ——發送某個鍵到指定元素

將元素拖拽到目標位置:

element = driver.find_element_by_name("source")
target = driver.find_element_by_name("target")
 
from selenium.webdriver import ActionChains
action_chains = ActionChains(driver)
action_chains.drag_and_drop(element, target).perform()

執行鼠標操做的流程:

menu = driver.find_element_by_css_selector(".nav") #獲取element對象
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")  #獲取點擊對象
#建立鼠標對象
actions = ActionChains(driver)
#移動鼠標到對象
actions.move_to_element(menu)
#點擊對象
actions.click(hidden_submenu)
#執行操做
actions.perform()

(5)彈出對話框

class selenium.webdriver.common.alert.Alert(driver)

Alert內置支持處理彈窗對話框,方法:

  • accept()  :確認彈窗,用法:Alert(driver).appept()
  • authenticate(username,password) :將用戶名和密碼發送到authenticated對話框,隱含點擊肯定,用法:driver.switch_to.alert.authenticate('username','password')
  • dismiss() :取消確認
  • send_keys(keysToSend) :將密鑰發送到警報,keysToSend爲要發送的文本
  • text :獲取Alert的文本
import time
from selenium import webdriver
from selenium.webdriver.common.alert import Alert
driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.execute_script("alert('肯定');")  #彈出窗口
time.sleep(2)
print(driver.switch_to.alert.text) #獲取alert文本
alert=Alert(driver).accept()  #自動點擊肯定窗口

(6)鍵盤操做

class selenium.webdriver.common.keys.Keys

selenium提供一個keys包來模擬全部的按鍵操做,下面咱們介紹下一些經常使用的按鍵操做:

  • 回車鍵:Keys.ENTER
  • 刪除鍵:Keys.BACK_SPACE
  • 空格鍵:Keys.SPACE
  • 製表鍵:Keys.TAB
  • 回退鍵:Keys.ESCAPE
  • 刷新鍵:Keys.F5
  • 全選(ctrl+A):send_keys(Keys.CONTROL,'a')   #組合鍵須要用send_keys方法操做
  • 複製(ctrl+C):send_keys(Keys.CONTROL,'c')
  • 剪切(ctrl+X):send_keys(Keys.CONTROL,'x')
  • 粘貼(ctrl+V):send_keys(Keys.CONTROL,'v')

實現點擊頁面從python的pypi頁面下載selenium源碼包:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/5 13:05
# @Author  : Py.qi
# @File    : test5.py
# @Software: PyCharm
import requests
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
driver=webdriver.Chrome()
driver.get('https://pypi.org/')

element=driver.find_element_by_id('search')  #獲取輸入框
element.send_keys('selenium')  #搜索selenium包
element.send_keys(Keys.ENTER)  #按回車鍵

element_a=driver.find_element_by_link_text('selenium') #定位selenium包連接

ActionChains(driver).move_to_element(element_a).click(element_a).perform() #按左鍵點擊連接執行

element_down=driver.find_element_by_link_text('Download files')  #定位下載連接
ActionChains(driver).move_to_element(element_down).click(element_down).perform()  #按左鍵點擊連接

element_selenium=driver.find_element_by_link_text('selenium-3.13.0.tar.gz')  #定位元素selenium下載包連接
data=element_selenium.get_attribute('href')   #獲取連接地址
with open('selenium-3.13.0.tar.gz','wb') as f:
    source=requests.get(data).content   #請求下載連接地址獲取二進制包數據
    f.write(source)  #寫入數據
    f.close()
    
driver.quit()

(7)延時等待

目前,大多數Web應用程序都在使用AJAX技術。當瀏覽器加載頁面時,該頁面中的元素可能以不一樣的時間間隔加載。這使定位元素變得困難:若是DOM中還沒有存在元素,則locate函數將引起ElementNotVisibleException異常。使用等待,咱們能夠解決這個問題。等待在執行的操做之間提供了一些鬆弛 - 主要是使用元素定位元素或任何其餘操做。

Selenium Webdriver提供兩種類型的等待 - 隱式和顯式。顯式等待使WebDriver等待某個條件發生,而後再繼續執行。在嘗試查找元素時,隱式等待會使WebDriver輪詢DOM一段時間。

顯示等待:

顯示等待是根據定義的代碼,用於在進一步執行代碼以前等待某個條件發送,它提供了一些便捷方法,能夠編寫在僅須要等待的代碼上,實現方法須要WebDriverWait與ExpectedCondition結合使用:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/5 14:41
# @Author  : Py.qi
# @File    : test6.py
# @Software: PyCharm
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.Chrome()
driver.get('https://www.taobao.com/')
wait=WebDriverWait(driver,3)  #設置監聽driver等待時間3秒
input=wait.until(EC.presence_of_element_located((By.ID,'q'))) #設置等待條件爲id爲q的元素加載完成
button=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search')))  #設置等待條件爲class名爲btn-search的元素加載完成
print(input,button)

其餘等待條件:

  • title_is :標題是某內容
  • title_contains :標題包含某內容
  • presence_of_element_located :節點加載出來,傳入定位元組,如(By.ID, 'p')
  • 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 :節點可點擊
  • staleness_of :判斷一個節點是否仍在DOM,可判斷頁面是否已經刷新
  • element_to_be_selected :節點可選擇,傳節點對象
  • element_located_to_be_selected :節點可選擇,傳入定位元組
  • element_selection_state_to_be :傳入節點對象以及狀態,相等返回True,不然返回False
  • element_located_selection_state_to_be :傳入定位元組以及狀態,相等返回True,不然返回False
  • alert_is_present :是否出現警告

隱式等待:

當使用隱式等待執行測試的時候,若是Selenium沒有在DOM中找到節點,將繼續等待,超出設定時間後,則拋出找不到節點的異常。換句話說,當查找節點而節點並無當即出現的時候,隱式等待將等待一段時間再查找DOM,默認的時間是0,調用driver的implicitly_wait()方法實現隱式等待:

from selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(10) #隱式等待設置爲10等待時間
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")

(8)異常處理

全部webdriver代碼中發生的異常:

  • selenium.common.exceptions.WebDriverException  :webdriver基本異常
  • selenium.common.exceptions.UnknownMethodException  :請求的命名與URL匹配但該URL方法不匹配
  • selenium.common.exceptions.UnexpectedTagNameException :當支持類沒有得到預期的Web元素時拋出
  • selenium.common.exceptions.UnexpectedAlertPresentException :出現意外警報時拋出,一般在預期模式阻止webdriver表單執行任何更多命令時引起
  • selenium.common.exceptions.UnableToSetCookieException :當驅動程序沒法設置cookie時拋出
  • selenium.common.exceptions.TimeoutException :當命令沒有在足夠的時間內完成時拋出
  • selenium.common.exceptions.StaleElementReferenceException :當對元素的引用如今「陳舊」時拋出,陳舊意味着該元素再也不出如今頁面的DOM上
  • selenium.common.exceptions.SessionNotCreatedException :沒法建立新會話
  • selenium.common.exceptions.ScreenshotException :屏幕截圖錯誤異常
  • selenium.common.exceptions.NoSuchWindowException :當不存在要切換的窗口目標時拋出
  • selenium.common.exceptions.NoSuchElementException :沒法找到元素時拋出
  • selenium.common.exceptions.NoSuchCookieException :在當前瀏覽上下文的活動文檔的關聯cookie中找不到與給定路徑名匹配的cookie
  • selenium.common.exceptions.NoSuchAttributeException :沒法找到元素的屬性時拋出
  • selenium.common.exceptions.JavascriptException :執行用戶提供的JavaScript時發生錯誤
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/5 16:19
# @Author  : Py.qi
# @File    : test7.py
# @Software: PyCharm
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
try:
    element=driver.find_element_by_id('test')
    print(element)
except NoSuchElementException as e:
    print('元素不存在:',e)

#
元素不存在: Message: no such element: Unable to locate element: {"method":"id","selector":"test"}
  (Session info: chrome=67.0.3396.99)
  (Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.10240 x86_64)

(9)實例:抓取淘寶頁面商品信息

#!/usr/bin/env python
#coding:utf-8
import re
import pymongo
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from urllib.parse import quote
from selenium.common.exceptions import WebDriverException
from pyquery import PyQuery as pq
#連接mongodb數據庫
client=pymongo.MongoClient(host='localhost',port=27017)
db=client['taobao']
#定義無頭chrome
opt=webdriver.ChromeOptions()
opt.add_argument('--headless')
driver=webdriver.Chrome(chrome_options=opt)
#定義頁面等待時間
wait=WebDriverWait(driver,10)
#定義搜索商品名
uname='iPad'

#搜索商品
def search():
    try:
        url = 'https://s.taobao.com/search?q=' + quote(uname)
        driver.get(url)
        total=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.total')))
    except TimeoutException:
        return search()
    return total.text

#實現翻頁商品
def next_page(page):
    print('正在抓取第{}'.format(page))
    try:
        if page >= 1:
            input=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > input')))
            submit=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit')))
            input.clear()
            input.send_keys(page)
            submit.click()
            wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > ul > li.item.active > span'),str(page)))
            wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist .items .item')))

            get_products()
    except TimeoutException:
        next_page(page)
    except WebDriverException as e:
        print('index_page:',e)

#解析商品信息
def get_products():
    #print('開始解析頁面...')
    html = driver.page_source
    doc = pq(html, parser='html')
    items = doc('#mainsrp-itemlist .items .item').items()
    for i in items:
        product = {
            'image': 'https:' + i.find('.pic .img').attr('data-src'),
            'price': i.find('.price').text(),
            'deal': i.find('.deal-cnt').text(),
            'title': i.find('.title').text(),
            'shop': i.find('.shop').text(),
            'location': i.find('.location').text()
        }
        #print(product)
        save_to_mongo(product)

#保存到mongodb
def save_to_mongo(result):
    try:
        if db['collection_taobao'].insert(result):
            print('保存到mongodb成功!',result)
    except Exception:
        print('保存到mongodb失敗',result)

#主函數調用
def main():
    try:
        total=search()
        total=int(re.compile('(\d+)').search(total).group(1))
        for i in range(1,total+1):
            next_page(i)
    finally:
        driver.quit()

#執行函數入口
if __name__ == '__main__':
    main()

抓取頭條圖片:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/6 11:16
# @Author  : Py.qi
# @File    : toutiao.py
# @Software: PyCharm
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import WebDriverException,TimeoutException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
import time
from PIL import Image
from io import BytesIO
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

opt=webdriver.ChromeOptions()
opt.add_argument('--headless')
driver=webdriver.Chrome(chrome_options=opt)
wait=WebDriverWait(driver,10)

def index_page(url,text):
    try:
        driver.get(url)
        insid=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#rightModule > div.search-wrapper > div > div > div.tt-input.tt-input-group.tt-input-group--append > input')))
        insid.clear()
        insid.send_keys(text)
        insid.send_keys(Keys.ENTER)
        driver.switch_to.window(driver.window_handles[1])
        images=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'body > div > div.y-box.container > div.y-left.index-middle > div.tabBar > ul > li:nth-child(3)')))
        ActionChains(driver).move_to_element(images).click(images).perform()
        element=driver.find_element_by_id('footer')
        sum=0
        while sum < 8:
            ActionChains(driver).move_to_element(element).send_keys(Keys.DOWN).perform()
            time.sleep(1)
            sum+=1
        html=driver.page_source
        doc=pq(html,parser='html')
        items=doc('.index-middle .feedBox .sections .articleCard').items()

        for i in items:
            #print(i('.title-box a').attr('href'))
            img_url='https://www.toutiao.com/a' + str(i('.title-box a').attr('href')).split('/')[-2]
            driver.get(img_url)
            if driver.title == '404錯誤頁':
                continue
            else:
                wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.bui-box')))
                img_source=driver.page_source
                doc1=pq(img_source,parser='html')
                excent=doc1('.imageList .image-list .image-item').items()
                for item in excent:
                    image_url=item('.image-item-inner a').attr('href')
                    image_name='D:\images\\' + image_url.split('/')[-1] + '.jpg'
                    content=requests.get(image_url).content

                    im=Image.open(BytesIO(content))
                    im.save(image_name)

                    im.close()
                    print('保存圖片成功',image_name)
    except TimeoutException:
        print('超時')
    except WebDriverException:
        print('driverError')
    except Exception as e:
        print(e)



def main():
    url='https://www.toutiao.com'
    context='街拍'
    index_page(url,context)



if __name__ == '__main__':
    main()
View Code

其餘異常請查看官網文檔:http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions

其餘詳細使用方法參考官方文檔:http://selenium-python.readthedocs.io

相關文章
相關標籤/搜索