一、简介

自动化测模块,通过驱动浏览器,模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器。

二、安装

3.1、pip 安装

1
pip install selenium

3.2、安装驱动

注:安装完记得配置环境变量~ [path]

  • Firefox浏览器驱动:geckodriver

https://github.com/mozilla/geckodriver/releases

  • Chrome浏览器驱动:

http://chromedriver.storage.googleapis.com/index.html

  • IE浏览器驱动:IEDriverServer

http://selenium-release.storage.googleapis.com/index.html

  • Edge浏览器驱动:MicrosoftWebDriver

https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

  • Opera浏览器驱动:operadriver

https://github.com/operasoftware/operachromiumdriver/releases

  • PhantomJS浏览器驱动:phantomjs

https://phantomjs.org/download.html

三、基本使用

3.1、Options()

Chrome Options是一个配置chrome启动时属性的类,通过这个参数我们可以为Chrome添加如下参数:

1、基本参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from selenium import webdriver option = webdriver.ChromeOptions()
# 禁用显卡
option.add_argument('--disable-gpu')
# 替换UA
option.add_argument("--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36")
#指定浏览器分辨率
option.add_argument('window-size=1920x3000')
#谷歌文档提到需要加上这个属性来规避bug
option.add_argument('--disable-gpu')
#隐藏滚动条, 应对一些特殊页面
option.add_argument('--hide-scrollbars')
#不加载图片, 提升速度
option.add_argument('blink-settings=imagesEnabled=false')
#设置语言
options.add_argument('lang=zh_CN.UTF-8')
# 禁止策略化
options.add_argument('--disable-infobars')
# 解决DevToolsActivePort文件不存在的报错
options.add_argument('--no-sandbox')
# 指定浏览器分辨率
options.add_argument('window-size=1920x3000')
# 隐身模式(无痕模式)
bug options.add_argument('--incognito')
# 禁用javascript
options.add_argument('--disable-javascript')
# 最大化运行(全屏窗口),不设置,取元素会报错
options.add_argument('--start-maximized')
# 禁用浏览器正在被自动化程序控制的提示
options.add_argument('--disable-infobars')
# 隐藏滚动条, 应对一些特殊页面
options.add_argument('--hide-scrollbars')
# 开启无界面模式. linux下如果系统不支持可视化不加这条会启动失败
options.add_argument('--headless')
#开发者模式
options.add_experimental_option('excludeSwitches', ['enable-automation'])
# 屏蔽'保存密码'提示框
options.add_experimental_option("prefs", prefs)
# 手动指定使用的浏览器位置
options.binary_location = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
driver = webdriver.Chrome(chrome_options = options) driver.get('https://www.baidu.com')

2、设置代理

方法1:

1
ip_info="182.14.2.3:29" options.add_argument("--proxy-server=http://{}".format(ip_info))   #设置代理

方法2:

更新代理:

1
2
3
4
5
6
7
8
9
10
11
proxy = Proxy(
{
'proxyType': ProxyType.MANUAL,
'httpProxy': '{}'.format(ip_info) # 代理ip和端口
#'httpProxy': '{}'.format("11.2.2.22:8080") # 代理ip和端口
}
)

desired_capabilities = webdriver.DesiredCapabilities.CHROME.copy()
proxy.add_to_capabilities(desired_capabilities)
driver.start_session(desired_capabilities)

3、关闭selenium关闭左上方Chrome 正受到自动测试软件的控制的提示

1
options.add_experimental_option('useAutomationExtension', False) options.add_experimental_option("excludeSwitches", ['enable-automation'])

3.2、打开一个测试窗口

1.通过谷歌浏览器驱动,打开谷歌浏览器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from selenium import webdriver
import time

# 打开浏览器方式一
driver = webdriver.Chrome(executable_path=r'C:\Users\Administrator\Desktop\chromedriver.exe')

# 打开浏览器方式二 推荐 []需要配置环境变量]
driver = webdriver.Chrome()

browser.get('https://www.baidu.com')
input = browser.find_element_by_id('kw')#找到搜索框 ,根据id找
input.send_keys('iPhone')#传送入关键词
# time.sleep(5)
# input.clear()#清空搜索框
# input.send_keys('1111') #输入1111
button = browser.find_element_by_id('su')#找到搜索按钮
button.click() #点击

3.3、关闭测试窗口

1
2
driver.close() #关闭单个窗口   #linux可能出现问题 
driver.quit() #关闭所有窗口

3.4、获取部分信息

1、获取url

1
h=driver.get(url)

2、获取cookie

1
cookie=dervr.get_cookie()

3、获取值

  • get_attribute()
1
b= browser.find_element_by_id('kw').get_attribute('href')
  • text
1
b= browser.find_element_by_id('kw').text

4、tag_name来获取元素的标签信息

1
b= browser.find_element_by_id('kw').tag_name

3.5、等待

由于可能出现页面未加载,就执行其他代码的情况,因此,需要添加等待

1、强制等待

time.sleep()

2、隐式等待

隐式等待:在查找所有元素时,如果尚未被加载,则等10秒

隐式等待只需要设置一次,在设置时间内,页面加载就停止等待

超过时间,会报错

browser.implicitly_wait(10)

3、显式等待

等待一个元素加载处理

1
2
3
4
5
6
7
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.ID, "kw")),message='元素kw未出现')

  • .判断当前页面的title是否精确等于预期
1
WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道"))
  • .判断当前页面的title是否包含预期字符串
1
WebDriverWait(driver,10).until(EC.title_contains(u"百度一下"))
  • 判断某个元素是否被加到了dom树里,并不代表该元素一定可见,通俗易懂点就是元素存不存在这个页面
1
WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
  • 判断是否至少有1个元素存在于dom树中,如果页面上有n个元素的class都是’column-md-3’,那么只要有1个元素存在,这个方法就返回True
1
WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.ID, "kw")))
  • 判断某个元素是否可见.可见代表元素非隐藏,并且元素的宽和高都不等于0
1

WebDriverWait(driver, 5).until(EC.visibility_of_element_located((By.ID, ‘k’)))

  • 判断元素是否可见,如果可见就返回这个元素
1
WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')))
  • 判断某个元素是否被选中了,一般用在下拉列表
1
WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]")))
  • 判断页面上是否存在alert,如果有就切换到alert并返回alert的内容
1
instance = WebDriverWait(driver,10).until(EC.alert_is_present())
  • 判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False
1
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator))

四、选择器

4.1、定位元素常用八种方法

1
2
3
4
5
6
7
8
driver.find_element_by_id()  #通过元素id定位
driver.find_element_by_name() #通过元素name定位
driver.find_element_by_xpath() #通过xpath表达式定位
driver.find_element_by_link_text() #通过完整超链接定位
driver.find_element_by_partial_link_text() #通过部分链接定位
driver.find_element_by_tag_name() #通过标签定位
driver.find_element_by_class_name() #通过类名进行定位
driver.find_element_by_css_selector() #通过css选择器进行定位
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
方式1:By.ID
driver.find_element_by_id()#通过ID属性定位唯一元素,多个的话默认取第一个
driver.find_elements_by_id()#通过ID属性定位多个元素,结果为列表
driver.find_elements_by_id()[3]#通过ID属性定位多个元素中的第3个
此处需注意,python中列表索引从0开始,但驱动浏览器执行时,相关执行语言中索引是从1开始哦!
方式2:By.NAME
driver.find_element_by_name()#通过NAME属性定位唯一元素,多个的话默认取第一个
driver.find_elements_by_name()#通过NAME属性定位多个元素,结果为列表
driver.find_elements_by_name()[3]#通过NAME属性定位多个元素中的第3个
方式3:By.CLASS_NAME
driver.find_elements_by_class_name()#通过类名定位唯一元素,多个的话默认取第一个
driver.find_elements_by_class_name()#通过类名定位多个元素,结果为列表
driver.find_elements_by_class_name()[3]#通过类名定位多个元素中的第3个
方式4:By.TAG_NAME
driver.find_element_by_tag_name()#通过标签名定位唯一元素,多个的话默认取第一个
driver.find_elements_by_tag_name()#通过标签名定位多个元素,结果为列表
driver.find_elements_by_tag_name()[3]#通过标签名定位多个元素中的第3个
方式5:By.LINK_TEXT
driver.find_element_by_link_text()#通过超链接(a标签)的文本定位唯一元素,多个的话默认取第一个
driver.find_elements_by_link_text()#通过超链接(a标签)的文本定位多个元素,结果为列表
driver.find_elements_by_link_text()[3]#通过超链接(a标签)的文本定位多个元素中的第3个
方式6:By.PARTIAL_LINK_TEXT
driver.find_element_by_partial_link_text()#通过超链接(a标签)的部分文本定位唯一元素,多个的话默认取第一个
driver.find_elements_by_partial_link_text()#通过超链接(a标签)的部分文本定位多个元素,结果为列表
driver.find_elements_by_partial_link_text()[3]#通过超链接(a标签)的部分文本定位多个元素中的第3个
方式7:By.CSS_SELECTOR(几乎万用,更切合前端CSS样式语言)
driver.find_element_by_css_selector()#通过CSS选择器定位唯一元素,多个的话默认取第一个
driver.find_elements_by_css_selector()#通过CSS选择器定位多个元素,结果为列表
driver.find_elements_by_css_selector()[3]#通过CSS选择器定位多个元素中的第3个
未完待续
方式8:By.XPATH(几乎万用,更切合后端XML语言)
driver.find_element_by_xpath() #通过XPATH定位唯一元素,多个的话默认取第一个
driver.find_elements_by_xpath() #通过XPATH定位多个元素,结果为列表
driver.find_elements_by_xpath() [3]#通过XPATH定位多个元素中的第3个

4.3、鼠标操作

1、基本操作

1
2
3
4
5
perform()	执行ActionsChains类中存储的所以行为
context_click() 右击
double_click() 双击
drag_and_drop() 拖动
move_to_element() 鼠标悬停

2、拖拽

1
2
3
from selenium.webdriver.common.action_chains import ActionChains
action_chains = webdriver.ActionChains(driver)
action_chains.drag_and_drop_by_offset(source, targetOffsetX - 2, 0).perform()

4.4、键盘操作

使用send_keys()方法时,需要先进行以下的导入

1
2
3
4
from selenium.webdriver.common.keys import Keys
#找到提交按钮
buttion_search = browser.find_element_by_class_name('s_search')
buttion_search.click() #相当于点击按钮
方法 对应键盘操作
send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
send_keys(Keys.SPACE) 空格键(Space)
send_keys(Keys.TAB) 指标键
send_keys(Keys.ESCAPE) 回退键()Esc
send_keys(Keys.ENTER) 回车键
send_keys(Keys.CONTROL,‘a’) 全选(ctrl +a)
send_keys(Keys.CONTROL,‘c’) 复制
send_keys(Keys.CONTROL,‘x’) 剪切
send_keys(Keys.CONTROL,‘v’) 粘贴
send_keys(Keys.F1) 键盘F1

4.5、Frame窗口切换

1
2
3
driver.switch_to.frame() 切换窗口

driver.switch_to.frame(driver.find_element_by_id("iframe")) #切换到frame里边

4.6、根据元素定位坐标

1
2
3
kw = self.driver.find_element_by_id('kw') 
kw_x = kw.location.get('x')#百度搜索框的x坐标
kw_y = kw.location.get('y')#百度搜索框的y坐标

4.7、根据坐标进行点击

1
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains ActionChains(dr).move_by_offset(500, 100).click().perform()

4.8、弹窗处理

当页面出现了弹窗提示

1
alert = driver.switch_to_alert()

4.9、展开shadow-root

1
2
3
4
5
6
7
8
#但是在最新版本的chrome 无法使用
def show_shadow(element):
# 展开shadow
shadow_root = browser.execute_script('return arguments[0].shadowRoot', element)
return shadow_root
domain_view = browser.find_element_by_tag_name('ip-address-view') # 找到name=domain-view的元素
shadow = show_shadow(domain_view) # 展开shadowRoot
report = shadow.find_element_by_id('report') # 找到id为report的元素

4.10、页面切换

一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。切换窗口的方法如下:

1
driver.switch_to.window("this is window name")

4.11、execute_script

有些在页面上无法定位的元素,需要执行js操作的时候,就需要用此方法

1
2
3
execute_script(script, *args)

js="window.scrollTo(0,document.body.scrollHeight)" #scrollTo滚动条 driver.execute_script(js)