自动化之Selenium+Python

一、安装导入库

1、从selenium里面导入webdriver模块

1
from selenium import webdriver

2、导入time模块,time模块是Python自带的,所以无需下载

1
import time

3、导入time模块下的ctime、sleep函数

1
from time import ctime,sleep

4、导入随机模块

1
import random  #随机数模块

二、定位方式

1
<input id="kw" class="s_ipt" type="text" autocomplete="off" maxlength="100" name="wd">

1、id定位

1
driver.find_element_by_id('kw')

2、name定位

1
find_element_by_name(‘wd’)

3、class定位

1
find_element_by_class_name(‘s_ipt’)

4、标签定位

1
find_element_by_tag_name(‘input’)
  1. 从上面定位到的元素属性中,可以看到每个元素都有tag(标签)属性,如搜索框的标签属性,就是最前面的input

  2. 很明显,在一个页面中,相同的标签有很多,所以一般不用标签来定位。

5、link定位

1
find_element_by_link_text()
  1. 定位百度页面上”hao123”这个按钮 查看页面元素:
1
<a class="mnav" target="_blank" href="http://www.hao123.com">hao123</a>
  1. 从元素属性可以分析出,有个href = "http://www.hao123.com

说明它是个超链接,对于这种元素,可以用link定位:

1
find_element_by_partial_link_text(“hao123”)
  1. 有时候一个超链接它的字符串可能比较长,如果输入全称的话,会显示很长,这时候可以用一模糊匹配方式,截取其中一部分字符串就可以了:
1
driver.find_element_by_partial_link_text('ao123')

6、xpath定位

1
2
3
4
5
driver.find_element_by_xpath('//input[@id="s_tab"]')
driver.find_element_by_xpath('//*[@id="s_tab"]]')
driver.find_element_by_xpath('//*[@id="s_tab"]/div/span')
driver.find_element_by_xpath('//*[@id="s_tab"]/div/a[2]')
driver.find_element_by_xpath('/html/body/div/div[2]/div[5]/div[1]/span[1]/input')

7、xpath:逻辑运算

  1. xpath还有一个比较强的功能,是可以多个属性逻辑运算的,可以支持与(and)、或(or)、非(not)

  2. 一般用的比较多的是and运算,同时满足两个属性

1
driver.find_element_by_xpath('//*[@id="s_tab" and @type=”text”]')

8、CSS定位

1
<input id="kw" class="s_ipt" type="text" autocomplete="off" maxlength="100" name="wd"/>
  1. css可以通过元素的id、class、标签这三个常规属性直接定位到

  2. css用#号表示id属性,如:#kw

  3. css用.表示class属性,如:.s_ipt

  4. css除了可以通过标签、class、id这三个常规属性定位外,也可以通过其它属性定位

  5. css也可以通过标签与属性的组合来定位元素

  6. css层级关系定位

  7. css也可以通过索引option:nth-child(1)来定位子元素

1
2
3
4
5
6
7
driver.find_element_by_css_selector(‘#kw’)			# CSS通过id属性定位
driver.find_element_by_css_selector(‘.s_ipt’) # CSS通过class属性定位
driver.find_element_by_css_selector(‘input’) # CSS通过标签定位
driver.find_element_by_css_selector(‘[autocomplete="off"]’) # CSS通过其他属性定位
driver.find_element_by_css_selector(‘input#kw’) # CSS标签和id属性组合定位
driver.find_element_by_css_selector(‘form#form>span>input’) # CSS通过层级关系定位
driver.find_element_by_css_selector(‘select#nr>option:nth-child(2)’) # CSS通过索引定位到第二个option标签

三、简单操作

1、打开浏览器 赋值给一个变量

1
2
3
driver = webdriver.Chrome()		# 打开谷歌浏览器
driver = webdriver.Ie() # 打开IE浏览器
driver = webdriver.Firefox() # 打开火狐浏览器

2、打开网页

1
driver.get('https://www.baidu.com')	# 打开百度

3、查看时间

1
print(time.ctime())   # 输出当前时间

4、等待sleep

1
time.sleep(3)        # 等待多少秒,再执行后续代码。单位是秒(s),时间值可以是小数也可以是整数

5、导入time模块下的ctime、sleep函数,查看时间、等待

1
2
3
from time import ctime,sleep
print(ctime())
sleep(3)

6、随机数

1
2
3
4
5
import random  #随机数模块

print(random.randint(0,100)) #randint随机的取规定范围中的数
a=[1,2,321,31,3,12,132]
print(random.choice(a)) #choice随机的取容器中的数据

7、刷新页面

1
driver.refresh()	# 刷新页面
  1. 有时候页面操作后,数据可能没及时同步,需要重新刷新

  2. 这里可以模拟刷新页面操作,相当于浏览器输入框后面的刷新按钮

8、前进和后退

1
2
driver.back()		# 回退到上个页面
driver.forward() # 切换到下个页面
  1. 当在一个浏览器打开两个页面后,想返回上一页面,相当于浏览器左上角的左箭头按钮

  2. 返回到上一页面后,也可以切换到下一页,相当于浏览器左上角的右箭头按钮

9、设置窗口大小

1
2
driver.set_window_size(540,960)	# 设置窗口大小为手机分辨率540*960
driver.maximize_window() # 窗口最大化
  1. 可以设置浏览器窗口大小,如设置窗口大小为手机分辨率540*960

  2. 也可以最大化窗口

10、截屏

1
driver.get_screenshot_as_file('C:\\Users\\Administrator\\Desktop\\test\\a01.jpg')
  1. 打开网站之后,也可以对屏幕截屏

  2. 截屏后设置制定的保存路径+文件名称+后缀

11、退出

1
2
driver.close()
driver.quit()
  1. 退出有两种方式,一种是close;另外一种是quit

  2. close用于关闭当前窗口,当打开的窗口较多时,就可以用close关闭部分窗口

  3. quit用于结束进程,关闭所有的窗口

12、点击(鼠标左键)页面按钮:click()

1
driver.find_element_by_id('su').click()

13、清空输入框:clear()

1
driver.find_element_by_id('su').clear()

14、输入字符串:send_keys()

1
driver.find_element_by_id('su').send_keys(‘我是字符串’)

15、submit提交表单

  1. 在百度搜索案例中,输入关键字后,可以直接按回车键搜索,也可以点搜索按钮搜索。

  2. submit()一般用来模拟回车键

1
driver.find_element_by_id('su').submit()

16、键盘操作

  1. selenium提供了一整套的模拟键盘操作事件,前面submit()方法如果不行的话,可以试试模拟键盘事件

  2. 模拟键盘的操作需要先导入键盘模块:from selenium.webdriver.common.keys import Keys

  3. 模拟enter键,可以用send_keys(Keys.ENTER)

1
driver.find_element_by_id('su').send_keys(Keys.ENTER)
  1. 其他常见键盘操作:
1
2
3
4
5
键盘 F1到F12:	send_keys(Keys.F1)  把F1改成对应的快捷键
复制 ctrl+C: send_keys(Keys.CONTROL,‘c’)
粘贴 ctrl+V: send_keys(Keys.CONTROL,‘v’)
复制 ctrl+A: send_keys(Keys.CONTROL,‘a’)
复制 ctrl+X: send_keys(Keys.CONTROL,‘x’)

17、鼠标悬停、右击、双击事件

  1. 鼠标不仅仅可以点击(click),鼠标还有其它的操作,如:鼠标悬停在某个元素上,鼠标右击,鼠标按住某个按钮拖到

  2. 鼠标事件需要先导入模块:

1
from selenium.webdriver.common.action_chains import ActionChains

perform() 执行所有ActionChains中的行为:

1
move_to_element() 鼠标悬停

这里以百度页面设置按钮为例:

1
2
3
4
# 鼠标悬停在搜索设置按钮上
mouse = driver.find_element_by_link_text(‘设置’)
ActionChains(driver).move_to_element(mouse).perform()
首先导入鼠标操作的模块 调用Actionchains()类 把浏览器也就是driver当做参数传入,后面是进行鼠标悬停,最后perform用来提交前面的操作

除了常用的鼠标悬停事件外,还有:

1
2
右击鼠标:context_click()
双击鼠标:double_click()

照葫芦画瓢,替换上面案例中对应的鼠标事件就可以了

18、获取当前窗口句柄

  1. 元素有属性,浏览器的窗口其实也有属性的,只是你看不到,浏览器窗口的属性用句柄(handle)来识别。

  2. 人为操作的话,可以通过眼睛看,识别不同的窗口点击切换。但是脚本没长眼睛,它不知道你要操作哪个窗口,这时候只能句柄来判断了。

  3. 获取当前页面的句柄:

1
2
driver.current_window_handle
h = driver.current_window_handle # 将获取的句柄赋值给一个变量,方便后续调用

19、获取所有句柄

  1. 点击打开跳转到一个新的窗口

  2. 点击后,获取当前的句柄:window_handles

1
h = driver.current_window_handle
  1. 获取所有句柄:
1
all_h = driver.window_handles

20、切换句柄

直接获取all_h这个list数据里面第二个handles的值,使用索引all_h[1]

1
driver.switch_to.window(all_h[1])

21、关闭新窗口,切回主页

  1. 打开新页面后,其实只想验证新页面跳转对不对,这里可以做个简单的验证,获取当前页面的title验证
1
print driver.title	# 打印当前窗口页面标题
  1. 验证完后切关闭新窗口
1
driver.close()
  1. 切回句柄到首页
1
driver.switch_window(h)
  1. 打印当前页面的句柄,看是否切换到首页
1
print driver.title

22、frameiframe的区别

frameiframe两者可以实现的功能基本相同,不过iframeframe具有更多的灵活性。 frame是整个页面的框架,iframe是内嵌的网页元素,也可以说是内嵌的框架

iframe标记又叫浮动帧标记,可以用它将一个HTML文档嵌入在一个HTML中显示。 它和frame标记的最大区别是在网页中嵌入 的<iframe></iframe>所包含的内容与整个页面是一个整体,而<frame></frame>所包含的内容是一个独立的个体,是可以独立显示的。另外,应用iframe还可以在同一个页面中多次显示同一内容,而不必重复这段内容的代码。

23、切换iframe

1
<iframe id="x-URS-iframe" frameborder="0" name="">
  1. switch_to_frame(driver.switch_to.frame())方法切换,此处有id属性,可以直接用id定位切换:
1
driver.switch_to.frame(x-URS-iframe)
  1. 如果iframe没有id怎么办?

① 这里iframe的切换是默认支持idname的方法的,当然实际情况中会遇到没有id属性和name属性为空的情况,这时候就需要先定位iframe

② 定位元素还是之前的方法同样适用,这里我可以通过tag先定位到,也能达到同样效果

1
2
iframe = driver.find_element_by_tag_name(‘iframe’)
driver.switch_to_frame(iframe)

24、释放iframe

iframe上的操作完后,想重新回到主页面上操作元素,这时候,就可以用switch_to_default_content()方法返回到主页面

1
driver.switch_to_default_content()

四、select

1
<select id="nr" name="NR">

选项有三个:

1
2
3
<option selected="" value="10">每页显示10条</option>
<option value="20">每页显示20条</option>
<option value="50">每页显示50条</option>

1、二次定位

基本思路:先定位select框,再定位select里的选项

1
2
s = driver.find_element_by_id(‘nr’)
s.find_element_by_xpath(‘//option[@value=’50’]’).click()

还可以直接把两步合并成为一步:

1
driver.find_element_by_id("nr").find_element_by_xpath("//option[@value='50']").click()

2、直接定位

自己写xpath定位或者css,一次性直接定位到option上的内容:

1
driver.find_element_by_xpath("//*[@id=’nr’]/option[2]").click()

3、Select模块(index)

  1. 除了上面介绍的两种简单的方法定位到select选项,selenium还提供了更高级的玩法,导入Select模块。直接根据属性或索引定位。

  2. 先要导入select方法:

1
from selenium.webdriver.support.select import Select

然后通过select选项的索引来定位选择对应选项(从0开始计数),如选择第三个选项:select_by_index(2)

1
2
s = driver.find_element_by_id(‘nr’)
Select(s).select_by_index(2)

4、Select模块(value)

  1. Select模块里面除了index的方法,还有一个方法,通过选项的value值来定位。每个选项,都有对应的value值:
1
2
3
4
<select id="nr" name="NR">
<option selected="" value="10">每页显示10条</option>
<option value="20">每页显示20条</option>
<option value="50">每页显示50条</option>

第二个选项对应的value值就是"20"select_by_value("20")

1
2
s = driver.find_element_by_id(‘nr’)
Select(s).select_by_value(‘20’)

5、Select模块(text)

  1. Select模块里面还有一个更加高级的功能,可以直接通过选项的文本内容来定位。

  2. 定位“每页显示50条”:select_by_visible_text("每页显示50条")

1
2
s = driver.find_element_by_id(‘nr’)
Select(s).select_by_visible_text(‘每页显示50条’)

五、弹窗alert\confirm\prompt

1
2
3
4
5
6
7
8
alert:
alert('我是alert')

confirm:
confirm('我是confirm')

prompt:
prompt('我是prompt')

UwGBnJ.png

1、alert操作

  1. 先用switch_to_alert()方法切换到alert弹出框上
1
t = driver.switch_to_alert()
  1. 可以用text方法获取弹出的文本 信息
1
print(t.text)	# 打印警告框文本内容
  1. accept()点击确认按钮
1
t.accept()
  1. dismiss()相当于点右上角x,取消弹出框
1
t.dismiss()

2、confirm操作

  1. 先用switch_to_alert()方法切换到confirm弹出框上
1
t = driver.switch_to_alert()
  1. 可以用text方法获取弹出的文本 信息
1
print(t.text)	# 打印警告框文本内容
  1. accept()点击确认按钮
1
t.accept()
  1. dismiss()点击取消弹按钮
1
t.dismiss()

3、prompt操作

  1. 先用switch_to_alert()方法切换到prompt弹出框上
1
t = driver.switch_to_alert()
  1. 可以用text方法获取弹出的文本 信息
1
print(t.text)	# 打印警告框文本内容
  1. send_keys() 这里多个输入框,可以用send_keys()方法输入文本内容
1
t.send_keys(‘hello selenium’)
  1. accept()点击确认按钮
1
t.accept()
  1. dismiss()相当于点右上角x,取消弹出框
1
t.dismiss()

六、单选框和复选框

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 单选框 -->
<div>性别:
<label><input type="radio" name="sex" value="男生">男生</label>
<label><input type="radio" name="sex" value="女生">女生</label>
</div>


<!-- 复选框 -->
<div>
爱好:
<label><input type="checkbox" name="like" value="0">音乐</label>
<label><input type="checkbox" name="like" value="1">旅游</label>
</div>

其中在input标签外面加上lable标签的作用是在点击文字的时候也会选中或者取消,提高用户体验度
单选框是圆的;复选框是方的,这个是业界的标准

1、单选:radio

  1. 首先是定位选择框的位置

  2. 定位id,点击图标就可以了

2、复选框:checkbox

  1. 勾选单个框,可以根据它的id直接定位到点击就可以了

  2. 全部勾选

全部勾选,可以用到定位一组元素,复选框的type=checkbox,这里可以用xpath语法://*[@type='checkbox']

1
2
3
checkboxs = driver.find_elements_by_xpath(‘//*[@type='checkbox']’)
for i in checkboxs:
i.click()

注意:

find_elements是不能直接点击的,它是复数的,所以只能先获取到所有的checkbox对象,然后通过for循环去一个个点击操作

3、判断是否选中:is_selected()

没点击操作前,判断选项框状态:

1
2
s = driver.find_element_by_id(‘boy’).is_selected()
print(s) # 结果为False

点击后,判断选项框状态:

1
2
3
4
driver.find_element_by_id(‘boy’).click()

r = driver.find_element_by_id(‘boy’).is_selected()
print(r) # 结果为True

七、调用JS处理滚动条

当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的。

这时候需要借助滚动条来拖动屏幕,使被操作的元素显示在当前的屏幕上,这时候只能借助JS了。

execute_script(),可以直接执行js的脚本。

1、如果是一个页面自带的滚动条(即网页的的滚动条)

可直接用js

1
2
3
4
js = 'window.scrollTo(200,800)'
driver.execute_script(js)

# 同时向右移动200px,向下移动800px

或:

1
2
3
js="var q=document.documentElement.scrollLeft=200"
driver.execute_script(js)
# 向右移动200px

或:

1
2
3
js="var q=document.documentElement.scrollTop=200"
driver.execute_script(js)
# 向下移动200px

2、元素聚焦、如果不是window滚动条,是内嵌滚动条

例如是在一个表单中的

我们可以先定位一个元素,这个元素是需要拖动滚动条的(就是这个元素是要在拖动滚动条之后才能显示的),把滚动条拖动到这个元素的位置:

1
2
target = driver.find_element_by_id("元素的id")   #这里定位方式只要能定位到元素就行,用那种方式都行
driver.execute_script("arguments[0].scrollIntoView();", target)

八、cookie

虽然cookie相关操作在平常ui自动化中用得少,偶尔也会用到,比如登录有图形验证码,可以通过绕过验证码方式,添加cookie方法登录。

登录后换账号登录时候,也可作为后置条件去删除cookie然后下个账号登录

1、获取cookies:get_cookies()

  1. 获取cookies方法直接用:get_cookies()

  2. 先启动浏览器,获取cookies,打印出来发现是空:[]

1
print(driver.get_cookies())
  1. 打开百度首页后,重新获取cookies,打印出来,就有值了

2、获取指定name的cookie:driver.get_cookie(name)

  1. 获取cookies发现里面有多个cookie,有时候我们只需要其中的一个,把重要的提出来,比如登录的cookie

  2. 这里用get_cookie(name),指定对应的cookie的name值就行了,比如博客园的:.CNBlogsCookie

1
print(driver.get_cookie(name=’.CNBlogsCookie’))

3、清除指定cookie:delete_cookie()

  1. 为了进一步验证上一步获取到的就是登录的cookie,可以删除它看看页面什么变化
1
driver.delete_cookie(name=’.CNBlogsCookie’)
  1. 删除这个cookie后刷新页面,发现刚才的登录已经失效了,变成未登录状态了
1
driver.refresh()

4、清除所有cookies:delete_all_cookies()

清除所有cookies后登录状态也失效了,cookies为空[]

1
2
driver.delete_all_cookies()
print(driver.get_cookies())

5、add_cookie(cookie_dict):添加cookie的值

用于绕过验证码登录

验证码这种问题是比较头疼的,对于验证码的处理,不要去想破解方法,这个验证码本来就是为了防止别人自动化登录的。

对于验证码,要么是让开发在测试环境弄个万能的验证码,如:1234,要么就是尽量绕过去

5.1、fiddler抓包

  1. 登录后会生成一个已登录状态的cookie,那么只需要直接把这个值添加到cookies里面就可以了。

  2. 可以先手动登录一次,然后抓取这个cookie,这里就需要用抓包工具fiddler了

  3. 先打开登录界面,手动输入账号和密码(不要点登录按钮)

  4. 勾选记住密码,自动登录

  5. 打开fiddler抓包工具,此时再点登录按钮

  6. 登录成功后,再查看cookie变化,发现多了两组参数,多的这两组参数就是我们想要的,copy出来

UwvfzQ.png

5.2、添加cookie方法:driver.add_cookie()

  1. add_cookie(cookie_dict)方法里面参数是cookie_dict,说明里面参数是字典类型。

  2. 源码官方文档介绍:

1
2
3
4
5
6
7
8
9
add_cookie(self, cookie_dict)
Adds a cookie to your current session.
:Args:
- cookie_dict: A dictionary object, with required keys - "name" and "value";
optional keys - "path", "domain", "secure", "expiry"
Usage:
driver.add_cookie({'name' : 'foo', 'value' : 'bar'})
driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/'})
driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/', 'secure':True})
  1. 从官方的文档里面可以看出,添加cookie时候传入字典类型就可以了,等号左边的是name,等号左边的是value。

  2. 把前面抓到的两组数据(参数不仅仅只有name和value),写成字典类型

5.3、添加cookie

  1. 这里需要添加两个cookie,一个是.CNBlogsCookie,另外一个是.Cnblogs.AspNetCore.Cookies

  2. 我这里打开的网页是博客的主页:http://www.cnblogs.com,没进入登录页。

  3. 添加cookie后刷新页面,接下来就是见证奇迹的时刻了。

UwxNmn.png

  1. 最后用driver.refresh()刷新页面就可以了
点击查看

本文标题:自动化之Selenium+Python

文章作者:Mango

发布时间:2020年07月15日 - 21:49:20

最后更新:2020年07月29日 - 09:32:03

原始链接:https://mango185.github.io/post/f24ef6b7.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------------本文结束 感谢您的阅读-------------------