文章目录

  • 一、Python+Selenium配置
  • 二、启动浏览器
  • 2.1 普通启动方式
  • 2.2 Headless启动方式
  • 三、元素定位
  • 四、selenium三种等待方式
  • 4.1 强制等待
  • 4.2 隐性等待
  • 4.3 显性等待
  • 五、浏览器操作
  • 5.1 将浏览器最大化显示
  • 5.2 将浏览器最小化显示
  • 5.3 设置浏览器宽1366、高768显示
  • 5.4 浏览器前进、后退、退出、关闭
  • 六、.操作元素对象
  • 七、键盘事件
  • 八、.鼠标事件
  • 九、.多层框架/层级定位
  • 十、Selenium速查表


一、Python+Selenium配置

  • 前提条件: 已安装好Python开发环境,版本3.5以上
  • 安装步骤:

1.1 打开cmd 输入pip install selenium 点击回车键,具体如下图

selenium headless模式下最大化窗口 selenium最小化运行_Chrome


selenium headless模式下最大化窗口 selenium最小化运行_百度_02

1.2 把下载好的chromedriver.exe放到Python安装目录下,下载方法

二、启动浏览器

2.1 普通启动方式

#!/usr/bin/python3
# encoding:utf-8
from selenium  import webdriver

#启动Firefox浏览器
#browser = webdriver.Firefox()
#启动IE浏览器
#browser = webdriver.Ie()
#启动Chrome浏览器
#指定驱动方式启动:webdriver.Chrome(executable_path="D://chromedriver.exe")
browser = webdriver.Chrome()
browser.get("http://www.baidu.com")

2.2 Headless启动方式

说明:浏览器的无界面形态,无需打开浏览器即可运行,此种方式只chrome60+版本

#!/usr/bin/python3
# encoding:utf-8
from selenium import webdriver

chrome_hless = webdriver.ChromeOptions()
# 使用headless无界面浏览器模式
chrome_hless.add_argument('--headless') 
chrome_hless.add_argument('--disable-gpu') 

# 启动浏览器,获取网页源代码
browser = webdriver.Chrome(chrome_options=chrome_hless)
mainUrl = "https://www.baidu.com/"
browser.get(mainUrl)
print(browser.title)
browser.quit()

''' 
运行之后结果打印百度标题:
百度一下,你就知道
'''

三、元素定位

元素

定位方法

id

find_element_by_id()

name

find_element_by_name()

class

find_element_by_class_name()

link_text

find_element_by_link_text(“全部文字匹配”)

partial_link_text

find_element_by_partial_link_text(“部分文字匹配”)

tag

find_element_by_tag_name()

xpath

find_element_by_xpath()

css

find_element_by_css_selector()

详见Python + Selenium 元素定位详细

四、selenium三种等待方式

4.1 强制等待

固定等待XX秒时长

from selenium import webdriver
   import time
   time.sleep(3)

4.2 隐性等待

设置最长等待时长XX秒:

  • 第一种情况:最长等待时长内浏览器一旦加载完成,直接进行下一步操作
  • 第二种情况:超出设置最长等待时长,再进行下一步操作
# 浏览器加载完成,即进行下一步操作,如果10秒钟还未加载完成,也进行下一步操作
driver.implicitly_wait(10)

4.3 显性等待

WebDriverWait,配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了。它主要的意思就是:程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException

wait模块的WebDriverWait类是显性等待类,先看下它有哪些参数与方法:

selenium.webdriver.support.wait.WebDriverWait(类)
init

driver: 传入WebDriver实例,即我们上例中的driver
timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒
ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常,则不中断代码,继续等待,如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException。

until

method: 在等待期间,每隔一段时间(__init__中的poll_frequency)调用这个传入的方法,直到返回值不是False
message: 如果超时,抛出TimeoutException,将message传入异常

until_not

与until相反,until是当某元素出现或什么条件成立则继续执行,
until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。

具如下

WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)

特别注意的是until或until_not中的可执行方法method参数,很多人传入了WebElement对象,如下:

WebDriverWait(driver, 10).until(driver.find_element_by_id(‘kw’)) # 错误

这是错误的用法,这里的参数一定要是可以调用的,即这个对象一定有 call() 方法,否则会抛出异常:

TypeError: ‘xxx’ object is not callable
在这里,你可以用selenium提供的 expected_conditions 模块中的各种条件,也可以用WebElement的 is_displayed() 、is_enabled()、**is_selected() **方法,或者用自己封装的方法都可以

WebDriverWait 常用方法表

对象

动作

title_is

判断当前页面的title是否完全匹配

title_contains

判断当前页面的title是否包含预期字符串

presence_of_element_located

判断某个元素是否被加到了dom树里,并不代表该元素一定可见

visibility_of_element_located

判断某个元素是否可见.可见代表元素非隐藏,并且元素的宽和高都不等于0

visibility_of

跟上面的方法做一样的事情,只是上面的方法要传入locator,这个方法直接传定位到的element就好了

presence_of_all_elements_located

判断是否至少有1个元素存在于dom树中。举个例子,如果页面上有n个元素的class都是’column-md-3’,那么只要有1个元素存在,这个方法就返回True

text_to_be_present_in_element

判断某个元素中的text是否包含了预期的字符串

text_to_be_present_in_element_value

判断某个元素中的value属性是否包含了预期的字符串

frame_to_be_available_and_switch_to_it

判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False

invisibility_of_element_located

判断某个元素中是否不存在于dom树或不可见

element_to_be_clickable

判断某个元素中是否可见并且是enable的,这样的话才叫clickable

staleness_of

等某个元素从dom树中移除,注意,这个方法也是返回True或False

element_to_be_selected

判断某个元素是否被选中了,一般用在下拉列表

element_selection_state_to_be

判断某个元素的选中状态是否符合预期

element_located_selection_state_to_be

跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入locator

alert_is_present

判断页面上是否存在alert

源码举例

#coding=utf-8
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

base_url = "http://www.baidu.com"
driver = webdriver.Chrome()
driver.implicitly_wait(5)
'''隐式等待和显示等待都存在时,超时时间取二者中最大的'''
locator = (By.ID,'kw')
driver.get(base_url)

'''判断title是否存在,返回布尔值'''
WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道"))
if WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道")) :
    print("已找到标题百度一下,你就知道")
WebDriverWait(driver,10).until(EC.title_contains(u"百度一下"))

'''判断某个元素是否被加到了dom树里,并不代表该元素一定可见,如果定位到就返回WebElement'''
srk = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
#百度输入框,输入selenim
srk.send_keys("selenim")

'''判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0'''
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su')))

'''判断元素是否可见,如果可见就返回这个元素WebElement'''
WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')))

'''判断是否至少有1个元素存在于dom树中,如果定位到就返回WebElement列表'''
WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mnav')))

'''判断是否至少有一个元素在页面中可见,如果定位到就返回WebElement列表'''
WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.mnav')))

'''判断指定的元素中是否包含了预期的字符串,返回布尔值'''
WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[8]"),u'设置'))

'''判断指定元素的属性值中是否包含了预期的字符串,返回布尔值'''
WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),u'百度一下'))

'''判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False'''
#WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator))
#注意这里并没有一个frame可以切换进去

'''判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回这个元素'''
WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfEveryCookieWrap')))
#注意#swfEveryCookieWrap在此页面中是一个隐藏的元素

'''判断某个元素中是否可见并且是enable的,代表可点击'''
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))).click()
driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click()
'''等待某个元素从dom树中移除'''
#WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='wrapper']/div[6]/a[1]"))).click()
#WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su')))
#这里没有找到合适的例子

'''判断某个元素是否被选中了,一般用在下拉列表'''
WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]")))

'''判断某个元素的选中状态是否符合预期'''
WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"),True))

'''判断某个元素的选中状态是否符合预期'''
WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//*[@id='nr']/option[1]"),True))
driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click()

'''判断页面上是否存在alert,如果有就切换到alert并返回alert的内容'''
instance = WebDriverWait(driver,10).until(EC.alert_is_present())
print(instance.text)
instance.accept()

driver.close()

五、浏览器操作

5.1 将浏览器最大化显示

browser.maximize_window()

5.2 将浏览器最小化显示

browser.minimize_window()

5.3 设置浏览器宽1366、高768显示

browser.set_window_size(1366, 768)

5.4 浏览器前进、后退、退出、关闭

browser.forword()#前进
browser.back()#后退
browser.quit()#退出
browser.close()#关闭

六、.操作元素对象

对象-

动作

clear()

清空

send_keys()

键盘操作

click()

点击

submit()

提交

text

获取对象文本

get_attribute()

获取对象属性值

源码举例

#coding=utf-8
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

base_url = "http://www.baidu.com"

driver = webdriver.Chrome()
driver.get(base_url)
driver.implicitly_wait(5)
#clear() 清空
driver.find_element(By.ID,'kw').clear()

#send_keys()输入框键盘输入select
driver.find_element(By.ID,'kw').send_keys("select")

#click()点击对象
driver.find_element(By.ID,'su').click()

#submit()提交,注意类型type=‘submit’
driver.find_element(By.ID,'su').submit()

#text获取元素文本值
button_name = driver.find_element_by_id('su').text

#get_attribute("type") 获取属性值
button_type = driver.find_element_by_id('su').get_attribute("type")
if button_type == "submit":
    print("type为submit")

七、键盘事件

对象

动作

send_keys(Keys.TAB)

TAB

send_keys(Keys.ENTER)

回车

send_keys(Keys.F12)

F12

send_keys(Keys.CONTROL,‘a’)

ctrl+a

源码举例

#coding=utf-8
from selenium import webdriver
import time
#键盘操作必须输入包
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.implicitly_wait(5)

bdsrk = driver.find_element_by_id('kw')
bdsrk.send_keys('输入')

#TAB
bdsrk.send_keys(Keys.TAB)
time.sleep(3)

#回车
bdsrk.send_keys(Keys.ENTER)
time.sleep(3)

#ctrl+a 全选输入框内容 
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
time.sleep(3)

#F12
bdsrk.send_keys(Keys.F12)
driver.close()

八、.鼠标事件

对象

动作

click

单击

context_click()

右击

double_click()

双击

drag_and_drop()

拖动

move_to_element()

鼠标悬停

click_and_hold

按下鼠标左键在一个元素上

源码举例

#coding=utf-8
from selenium import webdriver
import time
#鼠标操作必须输入包
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.implicitly_wait(5)

bdsrk  = driver.find_element_by_id('kw')
#百度一下按钮
bdan = driver.find_element_by_id('su')

#视频链接
dt =driver.find_element_by_name("tj_trtieba")
time.sleep(3)

#单击
bdsrk.click()
time.sleep(3)

#右击
ActionChains(driver).context_click(bdsrk).perform()
time.sleep(3)

#双击
ActionChains(driver).double_click(bdan).perform()
time.sleep(3)

#鼠标拖放 从百度一下按钮拖动到新闻链接位置
ActionChains(driver).drag_and_drop(bdan,dt)
time.sleep(3)

#鼠标悬停
ActionChains(driver).move_to_element(dt).perform()
time.sleep(3)
driver.close()

九、.多层框架/层级定位

定位元素过程中经常会遇到找不到元素的问题,出现该问题一般都是以下因素导致:

  • 元素定位方法不对
  • 页面存在iframe或内嵌窗口
  • 页面超时
    webdriver 提供了一个 switch_to_frame 方法,可以很轻松的来解决这个问题。
#先找到到 ifrome1(id = from1)
browser.switch_to_frame("from1")

十、Selenium速查表

异常

描述

WebDriverException

所有webdriver异常的基类,当有异常且不属于下列异常时抛出

InvalidSwitchToTargetException

下面两个异常的父类,当要switch的目标不存在时抛出

NoSuchFrameException

当你想要用switch_to.frame()切入某个不存在的frame时抛出

NoSuchWindowException

当你想要用switch_to.window()切入某个不存在的window时抛出

NoSuchElementException

元素不存在,一般由find_element与find_elements抛出

NoSuchAttributeException

一般你获取不存在的元素属性时抛出,要注意有些属性在不同浏览器里是有不同的属性名的

StaleElementReferenceException

指定的元素过时了,不在现在的DOM树里了,可能是被删除了或者是页面或iframe刷新了

UnexpectedAlertPresentException

出现了意料之外的alert,阻碍了指令的执行时抛出

NoAlertPresentException

你想要获取alert,但实际没有alert出现时抛出

InvalidElementStateException

下面两个异常的父类,当元素状态不能进行想要的操作时抛出

ElementNotVisibleException

元素存在,但是不可见,不可以与之交互

ElementNotSelectableException

当你想要选择一个不可被选择的元素时抛出

InvalidSelectorException

一般当你xpath语法错误的时候抛出这个错

InvalidCookieDomainException

当你想要在非当前url的域里添加cookie时抛出

UnableToSetCookieException

当driver无法添加一个cookie时抛出

TimeoutException

当一个指令在足够的时间内没有完成时抛出

MoveTargetOutOfBoundsException

actions的move操作时抛出,将目标移动出了window之外

UnexpectedTagNameException

获取到的元素标签不符合要求时抛出,比如实例化Select,你传入了非select标签的元素时

ImeNotAvailableException

输入法不支持的时候抛出,这里两个异常不常见,ime引擎据说是仅用于linux下对中文/日文支持的时候

ImeActivationFailedException

激活输入法失败时抛出

ErrorInResponseException

不常见,server端出错时可能会抛出

RemoteDriverServerException

不常见,好像是在某些情况下驱动启动浏览器失败的时候会报这个错