什么是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