什麼是selenium
Selenium是一套完整的web應用程序測試系統,包含了測試的錄製(selenium IDE),編寫及運行(selenium remote control)和測試的並行處理(selenium grid)。Selenium的核心selenium core 基於jsunit,徹底由Javascript編寫,所以能夠用於任何支持javascript的瀏覽器上。
Selenium能夠模擬真實瀏覽器,自動化測試工具,支持多種瀏覽器,爬蟲中主要來解決javascript渲染問題。
Selenium基本使用
用python寫爬蟲的時候,主要是selenium的webdriver,咱們能夠經過下面的方式先看看selenium.webdriver支持哪些瀏覽器
python@pythontab.com:~/python35$ python
Python 3.5.2 (default, Aug 24 2016, 16:48:29)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.javascript
from selenium import webdriver
help(webdriver)
執行結果以下,從結果中咱們也能夠看出基本支持了常見的全部瀏覽器:
......
PACKAGE CONTENTS
android (package)
blackberry (package)
chrome (package)
common (package)
edge (package)
firefox (package)
ie (package)
opera (package)
phantomjs (package)
remote (package)
safari (package)
support (package)
webkitgtk (package)
......
這裏要說一下比較重要的phantomJS是一個而基於Webkit的服務端javascript API,支持Wed而不須要瀏覽器支持,其快速,原生支持各類Web標準:Dom處理,CSS選擇器,JSON等等。phantomJS能夠用用於頁面自動化,網路監測,網頁截屏,以及無界面測試
聲明瀏覽器對象
上面咱們知道了selenium支持不少的瀏覽器,可是若是想要聲明並調用瀏覽器測須要:
from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
這裏只寫了兩個例子,固然了其餘的支持的瀏覽器均可以經過這種方式調用
訪問頁面
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("http://www.pythontab.com")
print(browser.page_source)
browser.close()
上述代碼運行後,會自動打開chrome瀏覽器,並登錄百度打印百度首頁的源代碼,而後關閉瀏覽器
查找元素
單個元素查找
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("http://bbs.pythontab.com")
input_first = browser.find_element_by_id("q")
input_second = browser.find_element_by_css_selector("#q")
input_third = browser.find_element_by_xpath('//*[@id="q"]')
print(input_first)
print(input_second)
print(input_third)
browser.close()
這裏咱們經過三種不一樣的方式去獲取響應的元素,第一種是經過id的方式,第二個中是 CSS選擇器,第三種是xpath選擇器,結果都是相同的。
find_element_by_name
find_element_by_id
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
下面這種方式是比較通用的一種方式:這裏須要記住by模塊因此須要導入
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get("http://bbs.pythontab.com")
input_first = browser.find_element(By.ID,"q")
print(input_first)
browser.close()
這裏咱們經過三種不一樣的方式去獲取相應的元素,第一種是經過ID的方式,第二個中是CSS選擇器,結果都是相同的。
這裏列舉一下經常使用的查找元素方法:
find_element_by_name
find_element_by_id
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
下面這種方式是比較通用的一種方式:這裏須要記住by模塊因此須要導入
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get("http://bbs.pythontab.com")
input_first = browser.find_element(By.ID,"q")
print(input_first)
browser.close()
固然這種方法和上述的方式是通用的,browser.fing_element(by.ID、「q」)這裏By.ID中的ID能夠替換爲其餘幾個
多個元素查找
其實多個元素和單個元素的區別,舉個例子:find_element,其餘使用上沒什麼區別,通用其中的一個例子演示:
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("http://bbs.pythontab.com")
lis = browser.find_elements_by_css_selector('.service-bd li')
print(lis)
browser.close()
這樣得到就是一個列表
固然上面的方式也是能夠經過導入from selenium.webdriver.common.by.import by 這種方式實現lis=browseer.find_elements(By.CSS_SELEVTOR,service-bd li’)
一樣的在單個元素中查找的方法在多個元素查找中一樣存在:
find_elements_by_name
find_elements_by_id
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
元素交互操做
對於獲取的元素調用交互方法
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get("http://www.taobao.com")
input_str = browser.find_element_by_id('q')
input_str.send_keys("ipad")
time.sleep(1)
input_str.clear()
input_str.send_keys("MakBook pro")
button = browser.find_element_by_class_name('btn-search')
button.click()
運行的結果能夠看出程序會自動打開Chrome瀏覽器並打開淘寶輸入iPad,而後刪除,從新輸入MakBool
交互動做
將動做附加到動做鏈中串行執行
from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"
browser.get(url)
browser.switch_to.frame('iframeResult')
source = browser.find_element_by_css_selector('#draggable')
target = browser.find_element_by_css_selector('#droppable')
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()
執行javascript
這是一個很是有用的方法,這裏就能夠直接調用js方法來實現一些操做,
下面例子是經過登陸知乎而後經過js翻到頁面底部,並彈框提示
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("http://www.zhihu.com/explore")
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("To Bottom")')
獲取元素屬性
get_attribute('class')
from selenium import webdriver
browser = webdriver.Chrome()
url = ' https://www.zhihu.com/explore'
browser.get(url)
logo = browser.find_element_by_id('zh-top-link-logo')
print(logo)
print(logo.get_attribute('class'))
獲取文本值
from selenium import webdriver
browser = webdriver.Chrome()
url = ' https://www.zhihu.com/explore'
browser.get(url)
input = browser.find_element_by_class_name('zu-top-add-question')
print(input.text)
獲取ID,位置,標籤名
id
location
tag_name
size
from selenium import webdriver
browser = webdriver.Chrome()
url = ' https://www.zhihu.com/explore'
browser.get(url)
input = browser.find_element_by_class_name('zu-top-add-question')
print(input.id)
print(input.location)
print(input.tag_name)
print(input.size)
frame
在不少網頁中都是有Frame標籤,因此咱們爬取數據的時候就涉及到切入到frame中以及切出來的問題,經過下面的例子演示
這裏經常使用的是switch_to.from()和switch_to.parent_frame()
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
browser = webdriver.Chrome()
url = ' http://www.runoob.com/try/try...'
browser.get(url)
browser.switch_to.frame('iframeResult')
source = browser.find_element_by_css_selector('#draggable')
print(source)
try:
logo = browser.find_element_by_class_name('logo')
except NoSuchElementException:
print('NO LOGO')
browser.switch_to.parent_frame()
logo = browser.find_element_by_class_name('logo')
print(logo)
print(logo.text)
等待
當使用了隱式等待執行測試的時候,若是WebDriver沒有在DOM中找到元素,將繼續等待,超出設定時間後則拋出找不到元素的異常,換句話說,當查找元素或元素並無當即出現的時候,隱式等待將等待一段時間在查找DOM,默認的時間是0
隱式等待
到了必定的時間發現元素尚未加載,則繼續等待咱們指定的時間,若是超過了咱們指定的時間還沒喲加載就會拋出異常,若是沒有須要等待的時候就已經加載完畢就會當即執行
from selenium import webdriver
browser = webdriver.Chrome()
browser.implicitly_wait(10)
browser.get(' https://www.zhihu.com/explore')
input = browser.find_element_by_class_name('zu-top-add-question')
print(input)
顯示等待
指定一個等待條件,而且指定一個最長等待時間,會在這個時間內進行判斷是否知足等待條件,若是成立就會當即返回,若是不成立,就會一直等待,直到等待你指定的最長等待時間,若是仍是不知足,就會拋出異常,若是知足了就會正常返回
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
browser = webdriver.Chrome()
browser.get(' https://www.taobao.com/')
wait = WebDriverWait(browser, 10)
input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
print(input, button)
上述的例子中的條件:EC.presence_of)element_;pcated()是確認元素是否已經出現了
EC.element_of_element_located()是確認元素是否已經出現了EC.element_be_clickable()是確認元素是不是可點擊的
經常使用的判斷條件:
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 frame加載並切換
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 是否出現Alert
瀏覽器的前進和後退
back()
forward()
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get(' https://www.baidu.com/')
browser.get(' https://www.taobao.com/')
browser.get(' http://www.pythontab.com/')
browser.back()
time.sleep(1)
browser.forward()
browser.close()
cookie操做
get_cookies()
delete_all_cookes()
add_cookie()
from selenium import webdriver
browser = webdriver.Chrome()
browser.get(' https://www.zhihu.com/explore')
print(browser.get_cookies())
browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'zhaofan'})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies())
選項卡管理
經過執行js命令實現新開選項卡window.open()
不一樣的選項卡是存在列表裏browser.window_handles
經過browser.window_handles[0]就能夠操做第一個選項卡
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get(' https://www.baidu.com')
browser.execute_script('window.open()')
print(browser.window_handles)
browser.switch_to_window(browser.window_handles[1])
browser.get(' https://www.taobao.com')
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
browser.get(' http://www.pythontab.com')
異常處理
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
except TimeoutException:
print('Time Out')
try:
browser.find_element_by_id('hello')
except NoSuchElementException:
print('No Element')
finally:
browser.close()php