Python Selenium 常用功能(实战详解)

一、Python+Selenium配置

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

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

在这里插入图片描述
在这里插入图片描述

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 不常见,好像是在某些情况下驱动启动浏览器失败的时候会报这个错
posted @ 2020-04-09 07:43  天天向上327  阅读(3469)  评论(0编辑  收藏  举报