selenium 鼠标,键盘操作
1、打开和关闭网页
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#!/usr/bin/env python # -*- coding:utf-8 -*- from selenium import webdriver driver = webdriver.Firefox() # 也可指定驱动和浏览器 # binary = FirefoxBinary('/usr/bin/firefox') # driver = webdriver.Firefox(firefox_binary=binary, executable_path="/home/zk/scrapy_dazhong/geckodriver") # 设置初始坐标位置 driver.set_window_position(x = 500 , y = 60 ) # 设置窗口大小 # driver.set_window_size(width=300, height=200) # 将浏览器最大化显示 driver.maximize_window() # 打开浏览器并输入网址 driver.get( "http://www.baidu.com" ) |
1
2
3
4
5
6
7
8
9
10
11
12
|
# 后退访问页 # driver.back() # 前进访问页 # driver.forward() time.sleep( 10 ) # close()用于关闭当前窗口,quit()用于退出驱动程序并关闭所有相关窗口. driver.quit() # 关闭浏览器 # driver.close() |
2、获取信息
1
2
3
4
5
6
7
8
|
# 获取页面title now_title = driver.title print now_title # 获取当前url now_url = driver.current_url print now_url # 获取页面详情代码(HTML) print driver.page_source |
3、查找元素
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
41
42
|
""" 在webdriver中,支持的找元素的方法有 查找方法 对应元素 find_element_by_id id find_element_by_name name find_element_by_class_name class name find_element_by_tag_name tag name find_element_by_link_text link text find_element_by_partial_link_text partial link text find_element_by_xpath xpath find_element_by_css_selector css selector """ # 根据Id获取标签 inputelement = driver.find_element_by_id( 'kw' ) # 清除输入框内容 inputelement.clear() # 输入框输入信息 inputelement.send_keys( "biubiubiu" ) # 触发点击事件 driver.find_element_by_id( 'su' ).click() # 通过 submit() 来提交操作 driver.find_element_by_id( "dl_an_submit" ).submit() # 获取百度输入框的宽高 size = driver.find_element_by_id( "kw" ).size print size # 获取百度底部的文本信息 text = driver.find_element_by_id( "cp" ).text print text # 获取元素的属性值,可以是 id、name、type 或元素拥有的其它任意属性 attribute = driver.find_element_by_id( "kw" ).get_attribute( 'type' ) print attribute # 获取元素的结果是否可见,返回结果为 True 或 False result = driver.find_element_by_id( "kw" ).is_displayed() print result |
4、鼠标操作
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
|
""" ActionChains 类鼠标操作的常用方法: context_click() 右击 double_click() 双击 drag_and_drop() 拖动 move_to_element() 鼠标悬停在一个元素上 click_and_hold() 按下不放鼠标左键在一个元素 release() 在某个元素上释放鼠标 """ # 定位元素 right = driver.find_element_by_xpath( "kw" ) # 对定位到的元素执行鼠标右键操作 ActionChains(driver).context_click(inputelement).perform() # 对定位到的元素执行鼠标双击操作 ActionChains(driver).double_click(inputelement).perform() # ####鼠标拖动#### # 定位元素的原位置 element = driver.find_element_by_id( "lg" ) # 定位元素要移动到的目标位置 target = driver.find_element_by_class_name( "qrcode-img" ) # 执行元素的移动操作 ActionChains(driver).drag_and_drop(element, target).perform() time.sleep( 3 ) su = driver.find_element_by_id( "su" ) # 对定位到的元素执行鼠标移动到上面的操作 ActionChains(driver).move_to_element(su).perform() time.sleep( 3 ) # 对定位到的元素执行鼠标左键按下不放的操作 ActionChains(driver).click_and_hold(su).perform() # 在指定元素上释放鼠标 ActionChains(driver).release(su) |
实例:
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
41
42
43
|
# -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from time import sleep import random driver = webdriver.Firefox() driver.implicitly_wait( 10 ) driver.maximize_window() driver.get( 'http://sahitest.com/demo/dragDropMooTools.htm' ) dragger = driver.find_element_by_id( 'dragger' ) # 被拖拽元素 item1 = driver.find_element_by_xpath( '//div[text()="Item 1"]' ) # 目标元素1 item2 = driver.find_element_by_xpath( '//div[text()="Item 2"]' ) # 目标2 item3 = driver.find_element_by_xpath( '//div[text()="Item 3"]' ) # 目标3 item4 = driver.find_element_by_xpath( '//div[text()="Item 4"]' ) # 目标4 # action = ActionChains(driver) # 按下鼠标不放 ActionChains(driver).click_and_hold(on_element = dragger).perform() sleep( 3 ) for i in range ( 1 , 50 ): print "--->i" , i # 移动 110 ActionChains(driver).move_to_element_with_offset(to_element = dragger, xoffset = 60 , yoffset = 55 ).perform() sleep(random.randint( 3 , 5 ) / 100 ) # 释放鼠标 ActionChains(driver).release(on_element = dragger).perform() # action = ActionChains(driver) # action.drag_and_drop(dragger, item1).perform() # 1.移动dragger到目标1 # sleep(2) # action.click_and_hold(dragger).release(item2).perform() # 2.效果与上句相同,也能起到移动效果 # sleep(2) # action.click_and_hold(dragger).move_to_element(item3).release().perform() # 3.效果与上两句相同,也能起到移动的效果 # sleep(2) # action.drag_and_drop_by_offset(dragger, 400, 150).perform() # 4.移动到指定坐标 # action.click_and_hold(dragger).move_by_offset(400, 150).release().perform() # 5.与上一句相同,移动到指定坐标 # sleep(2) # driver.quit() # 借鉴其它大神的代码!!!具体忘记在哪看到的了,如有侵权,请告知,立改 |
5、键盘操作
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
|
""" 常用 send_keys(Keys.BACK_SPACE) 删除键(BackSpace) send_keys(Keys.SPACE) 空格键(Space) send_keys(Keys.TAB) 制表键(Tab) send_keys(Keys.ESCAPE) 回退键(Esc) send_keys(Keys.ENTER) 回车键(Enter) send_keys(Keys.CONTROL,'a') 全选(Ctrl+A) send_keys(Keys.CONTROL,'c') 复制(Ctrl+C) send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X) send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V) Keys 类所提供的按键请查阅 webdriver API """ # 输入框输入内容 driver.find_element_by_id( "kw" ).send_keys( "selenium" ) time.sleep( 3 ) # 删除最后一个字符 driver.find_element_by_id( "kw" ).send_keys(Keys.BACK_SPACE) time.sleep( 3 ) # 输入空格键+“教程” driver.find_element_by_id( "kw" ).send_keys(Keys.SPACE) driver.find_element_by_id( "kw" ).send_keys(u "教程" ) time.sleep( 3 ) # 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' ) time.sleep( 3 ) # 输入框重新输入内容,搜索 driver.find_element_by_id( "kw" ).send_keys(Keys.CONTROL, 'v' ) time.sleep( 3 ) # 通过回车键盘来代替点击操作 driver.find_element_by_id( "su" ).send_keys(Keys.ENTER) |
6、设置超时时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
""" sleep():设置固定休眠时间.python的time 包提供了休眠方法sleep(),导入time包后就可以使用sleep(),进行脚本的执行过程进行休眠. implicitly_wait():是 webdirver 提供的一个超时等待.隐示等待一个元素被发现,或一个命令完成.如果超出了设置时间的则抛出异常. WebDriverWait():同样也是 webdirver 提供的方法.在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常. """ # 隐示等待:implicitly_wait # 相当于设置全局的等待,在定位元素时,对所有元素设置超时时间,超出了设置时间则抛出异常 # 隐式等待使得WebDriver在查找一个Element或者Element数组时,每隔一段特定的时间就会轮询一次DOM,如果Element或数组没有马上被发现的话。 # 默认设置是0。 # 一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用 driver.implicitly_wait( 10 ) # WebDriverWait主要提供了两个方法,一个是until()(元素出现), 另外一个是until_not()(元素消失) # until(method, message=’’) # 调用该方法提供的驱动程序作为一个参数,直到返回值不为 False。 # until_not(method, message=’’) # 调用该方法提供的驱动程序作为一个参数,直到返回值为 False # 等待时长10秒,默认0.5秒询问一次 WebDriverWait(driver, 10 ).until( lambda x: x.find_element_by_id( "kw" )).send_keys( "yoyo" ) time.sleep( 3 ) # 判断id为kw元素是否消失,设置等待时长10秒,询问时间为1秒 is_disappeared = WebDriverWait(driver, 10 , 1 ).until_not( lambda x: x.find_element_by_id( "kw" ).is_displayed()) print is_disappeared |
7、定位一组对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
""" 使用场景: 批量操作对象,比如将页面上所有的 checkbox 都勾上 先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象.比如定位出页面上所有的 checkbox,然后选择最后一个. * find_elements 用于获取一组元素 元素存储在list中,可进行任意操作 """ # 选择页面上所有的 tag name 为 input 的元素 inputs = driver.find_elements_by_tag_name( 'input' ) # 选择页面上所有的 css name 为 input 的元素 inputs_ = driver.find_elements_by_css_selector( 'input[type=checkbox]' ) # 然后从中过滤出type为checkbox 的元素,单击勾选 for item in inputs: if item.get_attribute( 'type' ) = = 'checkbox' : item.click() |
8、层级定位
1
|
menu = driver.find_element_by_id( 'login-ul' ).find_element_by_link_text(u '关闭的项目' ).click() |
实例:
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
|
# 设置等待(low的办法) tmp = 10 while tmp > 0 : time.sleep( 3 ) result = driver.find_element_by_link_text(u "立即体验" ).is_displayed() print result tmp - = 1 if result: driver.find_element_by_link_text(u "立即体验" ).click() time.sleep( 10 ) tmp = 0 # 设置等待(较为方便) # WebDriverWait(driver, 30).until(lambda driver: driver.find_element_by_link_text(u"立即体验").is_displayed()) # driver.find_element_by_link_text(u"立即体验").click() print u "已跳转页面%s" % driver.current_url button_ = driver.find_elements_by_css_selector( 'button[data-toggle="dropdown"]' ) button_[ 0 ].click() # 在父亲元件下找到 link 为 Action 的子元素 time.sleep( 2 ) # 层级定位,先找到login-ul的列表,在找到列表的某个元素 menu = driver.find_element_by_id( 'login-ul' ).find_element_by_link_text(u '关闭的项目' ).click() # 找到元素直接click与下方方法结果一致 ActionChains(driver).click(menu).perform() |
9、IFrame标签
1
2
3
4
5
6
7
|
""" 在 web 应用中经常会出现 frame 嵌套的应用,假设页面上有 A、B 两个 frame, 其中 B 在 A 内,那么 定位 B 中的内容则需要先到 A,然后再到 B. switch_to_frame 方法可以把当前定位的主体切换了 frame 里 """ # 进入到iframe标签里 driver.switch_to_frame(name = "login_frame" ) |
实例:自动化登陆QQ邮箱,并获取所有的邮件标题的示例
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# 找到iframe中 driver.switch_to_frame(name = "login_frame" ) # 在当前iframe中匹配 user = driver.find_element_by_xpath( ".//*[@id='u']" ) user.send_keys( "帐号" ) # 输入你的账号 time.sleep( 1 ) password = driver.find_element_by_xpath( ".//*[@id='p']" ) password.send_keys( "密码" ) # 输入你的密码 time.sleep( 2 ) driver.find_element_by_xpath( ".//*[@id='login_button']" ).click() # 点击登陆按钮 print u "已跳转页面%s" % driver.current_url time.sleep( 5 ) # selenium.common.exceptions.WebDriverException: Message: TypeError: can't access dead object # 解决报错方法 driver.switch_to_default_content() # time.sleep(3) # QQ邮箱有独立密码设置的,需要增加此步骤,没有可以省略 js = 'document.getElementById("pp").setAttribute("_focus","1");' driver.execute_script(js) time.sleep( 2 ) # 匹配独立密码输入框 duli_pwd = driver.find_element_by_id( "pp" ) duli_pwd.send_keys( "密码" ) # 输入你的独立密码 # 点击独立密码登陆按钮 driver.find_element_by_xpath( ".//*[@id='btlogin']" ).click() time.sleep( 2 ) print u "已跳转页面%s" % driver.current_url time.sleep( 2 ) # #######################登陆成功后################################## # 登陆后点击收件箱 driver.find_element_by_xpath( ".//*[@id='folder_1']" ).click() # 切入邮箱的IFrame中 driver.switch_to_frame( "mainFrame" ) time.sleep( 5 ) def test(): # 获取网页信息 content = driver.page_source # lxml content_ = etree.HTML(content) # 查找是否有下一页的标签 next_page = content_.xpath( ".//*[@id='nextpage1']/text()" ) if not next_page: return # 未读邮件列表 if_mail_list = content_.xpath( ".//*[@class='i F']" ) # 已读邮件列表 im_mail_list = content_.xpath( ".//*[@class='i M']" ) for item in if_mail_list: from_name = item.xpath( "./tbody/tr/td[3]/table/tbody/tr/td[1]/nobr/span/text()" ) main_ = item.xpath( "./tbody/tr/td[3]/table/tbody/tr/td[3]/div[1]/u/text()" ) print u "未读--->" , u "来自:" , from_name[ 0 ].strip() if from_name else u "哦..." , u "主题:" , main_[ 0 ].strip() if main_ else u "没..." for item in im_mail_list: from_name = item.xpath( "./tbody/tr/td[3]/table/tbody/tr/td[1]/nobr/span/text()" ) main_ = item.xpath( "./tbody/tr/td[3]/table/tbody/tr/td[3]/div[1]/u/text()" ) print u "已读--->" , u "来自:" , from_name[ 0 ].strip() if from_name else u "哦..." , u "主题:" , main_[ 0 ].strip() if main_ else u "没..." time.sleep( 3 ) # 点击下一页 driver.find_element_by_xpath( ".//*[@id='nextpage1']" ).click() time.sleep( 3 ) test() if __name__ = = '__main__' : test() |
10、多窗口操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
""" 要想在多个窗口之间切换,首先要获得每一个窗口的唯一标识符号(句柄)通过获得的句柄来区别 分不同的窗口,从而对不同窗口上的元素进行操作 window_handles #返回的所有窗口的句柄到当前会话 switch_to_window() # 获得当前窗口 用于处理多窗口操作的方法,与我们前面学过的 switch_to_frame() 是类似,switch_to_window()用于 处理多窗口之前切换,switch_to_frame() 用于处理多框架的切换。# nowhandle=driver.current_window_handle# driver.find_element_by_xpath(".//*[@id='u1']/a[7]").click() """ time.sleep( 5 ) # print u"当前窗口", nowhandle# 打开注册新窗口 driver.find_element_by_xpath( ".//*[@id='TANGRAM__PSP_10__submitWrapper']/a[1]" ).click() time.sleep( 3 ) driver.implicitly_wait( 3 ) allhandles = driver.window_handles print u "所有窗口" , allhandles # 循环判断窗口是否为当前窗口 for handle in allhandles: if handle ! = nowhandle: # 跳转窗口 driver.switch_to_window(handle) print 'now register window!' # 切换到邮箱注册标签 driver.close() # 回到原先的窗口 driver.switch_to_window(nowhandle) driver.find_element_by_id( "kw" ).send_keys(u "注册成功!" ) |
11、alert/confirm/prompt操作
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
|
""" alert(弹框)/confirm(弹框带确认取消按钮)/prompt(带输入框的弹框) text 返回 alert/confirm/prompt 中的文字信息 accept 点击确认按钮 dismiss 点击取消按钮,如果有的话 send_keys 输入值,这个 alert\confirm 没有对话框就不能用了,不然会报错 """ # 进入iframe标签 driver.switch_to_frame( "i" ) time.sleep( 5 ) # 找到按钮点击 driver.find_element_by_xpath( "html/body/input" ).click() time.sleep( 3 ) # 获取网页上的警告信息 alert_obj = driver.switch_to_alert() time.sleep( 2 ) # 取警告信息,不能+() print alert_obj.text # 输入值(如果有的话) alert_obj.send_keys( "abc" ) time.sleep( 2 ) # 点击确认按钮 alert_obj.accept() # 点击取消按钮(如果有的话) alert_obj.dismiss() |
12、文件上传
1
2
3
4
5
6
|
driver.implicitly_wait( 3 ) # 定位上传按钮,添加本地文件 file_path = '/home/zk/testsub/abc.txt' # send_keys 不仅可以写入信息,也可以上传文件 driver.find_element_by_xpath( ".//*[@id='post-5071']/div/ol[3]/li[4]/label" ).send_keys(file_path) time.sleep( 2 ) |
13、文件下载
只是大致尝试了一下,具体情况等待以后有需求在测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
""" browser.download.dir 用于指定你所下载文件的目录 os.getcwd() 该函数不需要传递参数,用于返回当前的目录 application/octet-stream 为内容的类型 """ import os fp = webdriver.FirefoxProfile() fp.set_preference( "browser.download.folderList" , 2 ) fp.set_preference( "browser.download.manager.showWhenStarting" , False ) fp.set_preference( "browser.download.dir" , os.getcwd()) fp.set_preference( "browser.helperApps.neverAsk.saveToDisk" , "application/octet-stream" ) browser = webdriver.Firefox(firefox_profile = fp) browser.get( "https://pypi.python.org/packages/d0/b1/1c9d9cc3fd6c1cd802d897d78a9ea5ad01b07c6c0f422b235717b74270ae/selenium-3.7.0-py2.py3-none-any.whl#md5=52fc71d16b86204e467002c1930d7b65" ) browser.find_element_by_xpath( ".//*[@id='post-5071']/div/ol[3]/li[4]/label" ).click() |
14、执行JS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
""" webdriver 提供了 execute_script() 接口用来调用 js 代码。 执行 JS 一般有两种场景: 1:一种是在页面上直接执行 JS 2:另一种是在某个已经定位的元素上执行 JS execute_script(script, *args) 在当前窗口/框架 同步执行 javaScript script:JavaScript 的执行。 *args:适用任何 JavaScript 脚本 """ # ######通过 JS 隐藏选中的元素##########第一种方法: # 隐藏文字信息 driver.execute_script( '$("#tooltip").fadeOut();' ) time.sleep( 5 ) # 隐藏按钮: button = driver.find_element_by_class_name( 'btn' ) driver.execute_script( '$(arguments[0]).fadeOut()' ,button) |
实例:滑动滚动条
1
2
3
4
5
6
7
8
9
10
11
|
driver.find_element_by_id( "kw" ).send_keys( "selenium" ) driver.find_element_by_id( "su" ).click() time.sleep( 3 ) # 将页面滚动条拖到底部 js = "var q=document.documentElement.scrollTop=10000" driver.execute_script(js) time.sleep( 3 ) # 将滚动条移动到页面的顶部 js_ = "var q=document.documentElement.scrollTop=0" driver.execute_script(js_) time.sleep( 3 ) |
15、cookie操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
""" webdriver 操作 cookie 的方法有: get_cookies() 获得所有 cookie 信息 get_cookie(name) 返回特定 name 有 cookie 信息 add_cookie(cookie_dict) 添加 cookie,必须有 name 和 value 值 delete_cookie(name) 删除特定(部分)的 cookie 信息 delete_all_cookies() 删除所有 cookie 信息 """ # 把cookie保存到本地 post = {} cookie_items = driver.get_cookies() for cookie_item in cookie_items: post[cookie_item[ 'name' ]] = cookie_item[ 'value' ] cookie_str = json.dumps(post) with open ( 'cookie.txt' , 'w' ) as f: f.write(cookie_str) print ( "cookies信息已保存到本地" ) # 取出cookie with open ( 'cookie.txt' , 'r' , encoding = 'utf-8' ) as f: cookie = f.read() cookies = json.loads(cookie) |