码迷,mamicode.com
首页 > 其他好文 > 详细

selenium

时间:2018-08-04 21:03:33      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:条件   ref   应用程序   subject   表单   nes   index   单元   screens   

一、什么是Selenium

selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并行处理(Selenium Grid)。Selenium的核心Selenium Core基于JsUnit,完全由JavaScript编写,因此可以用于任何支持JavaScript的浏览器上。

selenium可以模拟真实浏览器,自动化测试工具,支持多种浏览器,爬虫中主要用来解决JavaScript渲染问题。

二、selenium基本使用

用python写爬虫的时候,主要用的是selenium的Webdriver,我们可以通过下面的方式先看看Selenium.Webdriver支持哪些浏览器

技术分享图片

执行结果如下,从结果中我们也可以看出基本山支持了常见的所有浏览器:

技术分享图片

这里要说一下比较重要的PhantomJS,PhantomJS是一个而基于WebKit的服务端JavaScript API,支持Web而不需要浏览器支持,其快速、原生支持各种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.baidu.com") # 打开链接
browser.save_screenshot(screenshot.png) #屏幕截图
print(browser.page_source) #获取JS渲染后的源代码
browser.close() #关闭

查找元素

单个元素查找

from selenium import webdriver

browser = webdriver.Chrome()

browser.get("http://www.taobao.com")
input_first = browser.find_element_by_id("q") #通过id
input_second = browser.find_element_by_css_selector("#q") #通过css选择器
input_third = browser.find_element_by_xpath(//*[@id="q"]) #通过xpath
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://www.taobao.com")
input_first = browser.find_element(By.ID,"q")
print(input_first)
browser.close()

多个元素查找

其实多个元素和单个元素的区别,举个例子:find_elements,单个元素是find_element,其他使用上没什么区别,通过其中的一个例子演示:

from selenium import webdriver


browser = webdriver.Chrome()
browser.get("http://www.taobao.com")
lis = browser.find_elements_by_css_selector(.service-bd li)
print(lis)
browser.close()

这样获得就是一个列表

技术分享图片

 

当然上面的方式也是可以通过导入from selenium.webdriver.common.by import By 这种方式实现

lis = browser.find_elements(By.CSS_SELECTOR,‘.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,然后删除,重新输入MakBook pro,并点击搜索

Selenium所有的api文档:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains

交互动作

将动作附加到动作链中串行执行

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() #执行动作链
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)#拖拽到某个坐标然后松开

move_by_offset(xoffset,yoffset)             #鼠标移动到距离当前位置(x,y)

move_to_element(to_element)               #鼠标移动到某个元素

move_to_element_with_offset(to_element,xoffset, yoffset) #将鼠标移动到距某个元素多少距离的位置

release(on_element=None)                     #在某个元素位置松开鼠标左键

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

获取文本值
text

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查找子类的,则必须切换到子类的frame,子类如果查找父类也需要先切换

这里常用的是switch_to.from()和switch_to.parent_frame()

实例:登录qq邮箱并发送邮件

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Chrome()
driver.implicitly_wait(10)
try:
    driver.get(https://mail.qq.com/)
    driver.maximize_window() #最大化
    driver.switch_to_frame(login_frame) #切换到login_frame
    locator1 = (By.ID,login_button)
    WebDriverWait(driver,20).until(EC.presence_of_element_located(locator1))
    driver.find_element_by_id(u).clear()
    driver.find_element_by_id(u).send_keys(xxxx)#输入qq账号
    time.sleep(1)
    driver.find_element_by_id(p).send_keys(xxxx)# 输入密码
    time.sleep(1)
    driver.find_element_by_id(login_button).click()#点击登录
    time.sleep(2)
    locator2 = (By.ID,btlogin)
    WebDriverWait(driver,20).until(EC.presence_of_element_located(locator2))
    driver.find_element_by_id(pp).clear()
    driver.find_element_by_id(pp).send_keys(xxxx)#输入安全密码
    driver.find_element_by_id(btlogin).click()#点击确认
    time.sleep(3)
    locator3 = (By.ID,composebtn)
    WebDriverWait(driver,20).until(EC.presence_of_element_located(locator3))
    driver.find_element_by_xpath(//*[@id="composebtn"]).click()
    time.sleep(2)
    driver.switch_to_frame(mainFrame)#切到mainFrame
    locator4 = (By.ID,toAreaCtrl)
    WebDriverWait(driver,20).until(EC.presence_of_element_located(locator4))
    driver.find_element_by_xpath(//*[@id="toAreaCtrl"]/div[2]/input).send_keys(xxxxx)
    time.sleep(1)
    driver.find_element_by_id(subject).send_keys(test)
    time.sleep(1)
    driver.switch_to_frame(driver.find_element_by_tag_name(iframe))
    driver.find_element_by_xpath(/html/body).send_keys(12345)
    driver.switch_to.parent_frame()#切回父类
    driver.find_element_by_xpath(//*[@id="AttachFrame"]/span/input).click()
    driver.find_element_by_link_text(发送).click()
    locator5 = (By.ID,sendinfomsg)
    WebDriverWait(driver, 20).until(EC.presence_of_element_located(locator5))
    print(driver.find_element_by_id(sendinfomsg).text)
except Exception as e:
    print(e)

实例二:

import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException

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)
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)))#等待input标签出现
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, .btn-search)))
print(input, button)

上述的例子中的条件:EC.presence_of_element_located()是确认元素是否已经出现了
EC.element_to_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

更多操作参考:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.support.expected_conditions

浏览器的前进和后退

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(https://www.python.org/)
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())#获取cookies
browser.add_cookie({name: name, domain: www.zhihu.com, value: zhaofan}) #添加cookies
print(browser.get_cookies())
browser.delete_all_cookies() #移除所有cookies
print(browser.get_cookies())

小结

导入webdriver
from selenium import webdriver
import time

#要想调用键盘按键操作需要引入keys包
from selenium.webdriver.common.keys import Keys

driver.get("http://www.baidu.com/")

# 获取css=#u1 > a:nth-child(1)文本内容
data = driver.find_element_by_css_selector(#u1 > a:nth-child(1)).text

# 打印数据内容
print(data) # 新闻

# 生成页面快照并保存
driver.save_screenshot("baidu.png")

# 搜索
# # id="kw"是百度搜索输入框,输入字符串"长城"
driver.find_element_by_id(kw).send_keys(长城)

# id="su"是百度搜索按钮,click()是模拟点击
driver.find_element_by_id(su).click()
time.sleep(1)
# 获取新的页面快照
driver.save_screenshot("长城.png")

# 打印网页渲染后的源代码
print(driver.page_source)

# 获取当前页面Cookie
print(cookies: ,driver.get_cookies())
#
#ctrl+a全选输入框内容
driver.find_element_by_id(kw).send_keys(Keys.CONTROL, a)
#ctrl+x剪切输入框内容
driver.find_element_by_id(kw).send_keys(Keys.CONTROL, x)
#
#输入框重新输入内容
driver.find_element_by_id(kw).send_keys(python)
#
# 模拟Enter回车键
driver.find_element_by_id(su).send_keys(Keys.RETURN)
time.sleep(5)
# 清空输入框内容
driver.find_element_by_id(kw).clear()
#生成新的页面快照
driver.save_screenshot(python.png)
#获取当前url
print(driver.current_url)

driver.quit()

driver.close()

 

选项卡管理

通过执行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(https://python.org)

异常处理

这里的异常比较复杂,官网的参考地址:
http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions
这里只进行简单的演示,查找一个不存在的元素

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

弹窗处理

当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法如下

alert = driver.switch_to_alert()
alert.accept()
print(alert)

phantomjs介绍

PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎。它原生支持多种web标准:DOM 操作,CSS选择器,JSON,Canvas 以及SVG。

phantomjs常用配置

# 引入配置对象DesiredCapabilities

fromselenium.webdriver.common.desired_capabilities import DesiredCapabilities

dcap =dict(DesiredCapabilities.PHANTOMJS)

#从USER_AGENTS列表中随机选一个浏览器头,伪装浏览器

dcap["phantomjs.page.settings.userAgent"]= (random.choice(USER_AGENTS))

# 不载入图片,爬页面速度会快很多

dcap["phantomjs.page.settings.loadImages"]= False

# 设置代理

service_args =[--proxy=127.0.0.1:9999,--proxy-type=socks5]

#打开带配置信息的phantomJS浏览器

driver =webdriver.PhantomJS(phantomjs_driver_path,desired_capabilities=dcap,service_args=service_args)

填充表单

我们已经知道了怎样向文本框中输入文字,但是其它的表单元素呢?例如下拉选项卡的的处理可以如下

首先获取了第一个 select 元素,也就是下拉选项卡。然后轮流设置了 select 选项卡中的每一个 option 选项。你可以看到,这并不是一个非常有效的方法。

其实 WebDriver 中提供了一个叫 Select 的方法,可以帮助我们完成这些事情。

如你所见,它可以根据索引来选择,可以根据值来选择,可以根据文字来选择。是十分方便的。

全部取消选择怎么办呢?很简单

这样便可以取消所有的选择。

另外我们还可以通过下面的方法获取所有的已选选项。

这样就相当于模拟点击了 submit 按钮,做到表单提交。

当然你也可以单独提交某个元素

方法,WebDriver 会在表单中寻找它所在的表单,如果发现这个元素并没有被表单所包围,那么程序会抛出 NoSuchElementException 的异常。

selenium

标签:条件   ref   应用程序   subject   表单   nes   index   单元   screens   

原文地址:https://www.cnblogs.com/woaixuexi9999/p/9419863.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!