一、浏览器操作相关
from selenium import webdriver driver = webdriver.Chrome() driver.maximize_window() # 窗口最大化 driver.set_window_size(400,800) # 设置窗口大小 driver.back() # 回退一层 driver.forward() # 前进一层 driver.quit() # 退出浏览器 driver.close() # 关闭浏览器
二、元素定位
# 根据id定位 driver.find_element_by_id("kw").send_keys("hello") # 根据name属性定位 driver.find_element_by_name("kw").send_keys("hello") # 根据class定位 driver.find_element_by_class_name("kw").send_keys("hello") # 根据链接文本内容定位,完全匹配 driver.find_element_by_link_text("kw").send_keys("hello") # 根据链接文本内容定位,模糊匹配 driver.find_element_by_partial_link_text("kw").send_keys("hello") # 根据标签名定位 driver.find_element_by_tag_name("kw").send_keys("hello") # 根据xpath定位 driver.find_element_by_xpath("kw").send_keys("hello") # 根据css定位 driver.find_element_by_css_selector("kw").send_keys("hello")
三、xpath 、 css适用定位
3.1、xpath定位
# 1.层级和属性结合定位 driver.find_element_by_xpath("//form[@id='login']/ul/input[1]") # 2.逻辑运算组合定位 driver.find_element_by_xpath("//input[@class='login' and @name='username']") # 3.根据部分元素属性定位(模糊定位) driver.find_element_by_xpath("//div[contains(@id, 'btn-attention')]") # 包含指定内容即可 driver.find_element_by_xpath("//div[starts-with(@id, 'btn-attention')]") # id以btn-attention driver.find_element_by_xpath("//div[ends-with(@id, 'btn-attention')]") # id以btn-attention')结尾 # 4. 通过子节点获取父节点 driver.find_element_by_xpath("//div[@id='C']/..).text # .表示当前节点 , ..表示父节点
3.2、css常用定位
selenium 极力推荐使用css定位,而不是xpath来定位元素,原因是css定位比xpath定位速度快,语法也更加简洁
# css常用定位方法 # 1.css定位 find_element_by_css_selector() # 2.根据id定位 #:id选择器,根据id属性来定位元素 # eg:driver.find_element_by_css_selector("#kw").send_keys("hello") # 3.根据class定位 .:class选择器,根据class属性来定位元素 # eg:driver.find_element_by_css_selector(".login").send_keys("hello") # 4.根据属性来定位 [attrbute='value']:根据属性来定位元素 # eg:driver.find_element_by_css_selector("[autocomplete='off']").send_keys("hello") # 5.根据元素层级来定位 element>element:根据元素层级来定位 父元素>子元素 #eg:driver.find_element_by_css_selector("form#login>ul>input").send_keys("hello") # login是form标签里面的id属性 # 6.多class属性定位(多个class之间直接用'.'符号连接) #eg:driver.find_element_by_css_selector(".register.login").send_keys("hello") # 7.兄弟元素定位 +:定位当前节点之后的第一个兄弟节点 ~:定位当前节点后面的所有兄弟节点,使用element定位默认取第一个,使用elements定位取到一组兄弟节点 #eg: driver.find_element_by_css_selector('div#D + div').text driver.find_element_by_css_selector('div#D ~ div').text
四、下拉菜单列表选项定位
1、使用上述xpath、css等方法可以实现
2、使用Select实现
导入:from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import Select select = Select(driver.find_element_by_css_selector("[name='selectinput']")) # 定位到下拉菜单组件 select.select_by_index(2) # 定位到index 第二个option元素 select.deselect_by_value(1) # 定位到属性value=1的option元素 select.select_by_visible_text("保留七天") # 根据内容直接定位指定option元素 select.all_selected_options # 所有option元素
五、鼠标操作
- 需要引入ActionChains类
- 然后定位相关元素
- 在ActionChains().调用相关鼠标操作方法
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains driver.find_element_by_css_selector("#kw").send_keys("Python") # 获取搜索框元素对象 element=driver.find_element_by_css_selector("#kw") #双击操作 ActionChains(driver).double_click(element).perform() #右击操作 ActionChains(driver).context_click(element).perform() #鼠标悬停 above=driver.find_element_by_css_selector(".pf") ActionChains(driver).move_to_element(above).perform()
#ActionChains操作方法列表 click(on_element=None) ——单击鼠标左键 click_and_hold(on_element=None) ——点击鼠标左键,不松开 context_click(on_element=None) ——点击鼠标右键 double_click(on_element=None) ——双击鼠标左键 drag_and_drop(source, target) ——拖拽到某个元素然后松开 drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开 key_down(value, element=None) ——按下某个键盘上的键 key_up(value, element=None) ——松开某个键 move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标 move_to_element(to_element) ——鼠标移动到某个元素 move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置 perform() ——执行链中的所有动作 release(on_element=None) ——在某个元素位置松开鼠标左键 send_keys(*keys_to_send) ——发送某个键到当前焦点的元素 send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素
六、键盘操作
from selenium import webdriver from selenium.webdriver.common.keys import Keys #键盘全选操作 Ctrl+A driver.find_element_by_css_selector("#kw").send_keys(Keys.CONTROL,'a') #键盘选择复制或剪切操作 Ctrl+C driver.find_element_by_css_selector("#kw").send_keys(Keys.CONTROL,'c') # 复制 driver.find_element_by_css_selector("#kw").send_keys(Keys.CONTROL,'x') # 剪切 #粘贴复制内容 driver.find_element_by_css_selector(".sec-input").send_keys(Keys.CONTROL,'v')
常用:
# 组合键操作 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.ENTER # 回车键 Keys.BACK_SPACE # 删除键 Keys.SPACE # 空格键 Keys.TAB # 制表键 Keys.ESCAPE # 回退键 Keys.F5 # 刷新键
七、元素等待
- 显示等待
- 隐式等待
有时候我们打开网页定位到某个元素,判断该元素是否存在,而网页打开花费的时间我们并不确定,通过元素等待操作可以让我们忽略这些问题。
- WebDriverWait 显示等待针对元素必用
- expected_conditions 预期条件类(里面包含方法可以调用,用于显示等待)
- NoSuchElementException 用于隐式等待抛出异常
- implicitly_wait 隐式等待
- By 用于元素定位
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait #注意字母大写 from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException
显示等待:
# 案例:检测百度页面搜索按钮是否存在,输入关键词“自学网 Selenium” ,如果存在则点击搜索 from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from time import sleep driver=webdriver.Firefox() driver.get("http://www.baidu.com") driver.find_element_by_css_selector("#kw").send_keys("自学网 Selenium") sleep(2) #显示等待--判断搜索按钮是否存在 element=WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,"su"))) # timeout:5秒,每0.5秒检测一次 element.click() sleep(3) driver.quit()
隐式智能等待:
from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from time import sleep,ctime driver=webdriver.Firefox() driver.get("http://www.baidu.com") sleep(2) driver.implicitly_wait(5) #隐式等待时间设定 5秒,等待时间内检测成功则不再等待,比sleep实用 #检测搜索框是否存在 try: print(ctime()) driver.find_element_by_css_selector("#kw").send_keys("Python") driver. find_element_by_css_selector("#su").click except NoSuchElementException as msg: print(msg) finally: print(ctime()) sleep(3) driver.quit()
八、frame嵌套页面元素定位
多层框架或窗口的定位:
- switch_to_frame() # frame定位
- switch_to_window() # window窗口定位
1、多层框架(frame)
1).定位frame的多种方式
from selenium import webdriver driver = webdriver.Firefox() driver.switch_to.frame(0) # 1.用frame的index来定位,第一个是0 # driver.switch_to.frame("frame1") # 2.用id来定位 # driver.switch_to.frame("myframe") # 3.用name来定位 # driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) # 4.用WebElement对象来定位
通常使用id或name就可以解决大多数frame定位问题,但当没有id 、name时,就要使用index、WebElement来定位了,,如下:
<iframe src="myframetest.html" />
使用xpath定位,传入WebElement对象:
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(@src,'myframe')]"))
2)、从frame切回主文档:
切到frame中之后,我们便不能继续操作主文档的元素,这时如果想操作主文档内容,则需切回主文档
driver.switch_to.default_content()
3)、嵌套frame的操作
需要一层一层往下定位,不能跳着定位
driver.switch_to.frame("frame1") # 先切到frame1(上级frame) driver.switch_to.frame("frame2") # 再切到frame2
4)、从子级frame切换到父级frame方法:
driver.switch_to.parent_frame() # 相当于后退一层。如果当前已是主文档,则无效果
有了parent_frame()
这个相当于后退的方法,我们可以随意切换不同的frame,随意的跳来跳去了。所以只要善用以下三个方法,遇到frame分分钟搞定
driver.switch_to.frame(reference)
driver.switch_to.parent_frame()
driver.switch_to.default_content()
demo:
# 案例:在Frame.html文件种定位搜狗搜索页面,进行搜索操作 from selenium import webdriver from time import sleep driver=webdriver.Firefox() #设置网页文件路径,r代表路径转义 file_path=r'E:\Python_script\Webdriver\Frame.html' #路径转义另一种写法 # file_path='E:\\Python_script\\Webdriver\\Frame.html' driver.get(file_path) #切换到frame页面内 driver.switch_to.frame("search") #定位到搜索框按钮输入关键词 driver.find_element_by_css_selector("#query").send_keys("Python") sleep(3) driver.find_element_by_css_selector("#stb").click() sleep(3) driver.quit()
2、多窗口操作
有些页面的链接打开后,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口了。获取窗口的唯一标识用句柄表示,所以只需要切换句柄,我们就能在多个页面上灵活自如的操作了
driver.current_window_handle # 获取当前句柄 driver.window_handles # 获取所有句柄 driver.switch_to.window() # 切换句柄 ,一个参数:窗口句柄
多窗口切换的两种方式:
方法一:
1.循环判断是否与首页句柄相等
2.如果不等,说明是新页面的句柄
3.获取的新页面句柄后,可以切换到新打开的页面上
4.打印新页面的title,看是否切换成功
方法二:
1.直接获取all_h这个list数据里面第二个hand的值
# 方法一:判断句柄,不等于首页就切换 for i in all_h: # all_h:所有窗口句柄 if i != h: driver.switch_to.window(i) print driver.title # 方法二:获取list里面第二个直接切换 driver.switch_to.window(all_h[1])
九、警告弹窗处理
在Webdriver中处理JavaScript生成的alert、confirm、prompt,使用switch_to_alert()方法定位到alert、confirm、prompt,然后进行如下操作:
- text:返回alert/confirm/prompt中的文字信息
- accept():接受现有警告框
- dismiss():解散现有警告框
- sendkeys(keysToSend):发送文本至警告框,如果没有对话框输入,不能用,否则会报错
demo:
点击百度首页设置按钮,然后进入搜索设置页面,点击“保存设置”或“恢复默认”按钮,处理警告弹窗窗口
from selenium import webdriver from time import sleep from selenium.webdriver.common.action_chains import ActionChains driver=webdriver.Firefox() driver.implicitly_wait(10) driver.get("http://www.baidu.com") # driver.find_element_by_link_text('设置').click() # 鼠标悬停字“设置”链接 link = driver.find_element_by_link_text('设置') ActionChains(driver).move_to_element(link).perform() # 打开搜索设置 driver.find_element_by_link_text('搜索设置').click() # 保存设置 driver.find_element_by_link_text('保存设置').click() # driver.find_element_by_link_text('恢复默认').click() # 打印警告框的文字信息 print(driver.switch_to_alert().text) # 接受警告框 driver.switch_to_alert().accept() driver.quit()
十、文件上传操作
1、文件上传
文件上传中,上传按钮的种类,大体上可以分为两种,一种是input框,另外一种就比较复杂,通过js、flash等实现,标签非input
1)input类型的上传按钮-上传文件
from selenium import webdriver driver = webdriver.Firefox() driver.get('http://sahitest.com/demo/php/fileUpload.htm') upload = driver.find_element_by_id('file') upload.send_keys(r'd:\baidu.py') # 直接send_keys print upload.get_attribute('value') # check value driver.quit()
2)非input类型的上传操作
大体上有以下几种解决方案:
-
autoIT
,借助外力,我们去调用其生成的au3或exe文件。 - Python
pywin32
库,识别对话框句柄,进而操作 -
SendKeys
库 -
keybd_event
,跟3类似,不过是模拟按键,ctrl+a,ctrl+c, ctrl+v...
本次只介绍第三种SendKeys方式
# 需安装:pip install SendKeys from selenium import webdriver import win32gui import win32con import time dr = webdriver.Firefox() dr.get('http://sahitest.com/demo/php/fileUpload.htm') upload = dr.find_element_by_id('file') upload.click() time.sleep(1) # SendKeys SendKeys.SendKeys('D:\\baidu.py') # 发送文件地址 SendKeys.SendKeys("{ENTER}") # 发送回车键 print upload.get_attribute('value') dr.quit()
注:多文件上传就是在文件路径框里用引号括起单个路径,然后用逗号隔开多个路径,就是这么简单,例如:
"D:\\a.txt","D:\\b.txt"
十一、浏览器滚动条操作
from selenium import webdriver from time import sleep driver=webdriver.Chrome() driver.get("http://www.baidu.com/") sleep(2) #将滚动调拖到最底部 js="var action=document.documentElement.scrollTop=10000" driver.execute_script(js) sleep(2) #将滚动条拖到最顶部 js="var action=document.documentElement.scrollTop=0" driver.execute_script(js) sleep(3)
# 鼠标下拉操作 target = driver.find_element_by_id("id_keypair") #找到目标元素 driver.execute_script("arguments[0].scrollIntoView();", target) #拖动到可见的元素(页面转到指定目标元素位置) # 鼠标下拉当前页面显示高度(数值) browser.execute_script("window.scrollTo(0, document.body.scrollHeight); var lenOfPage=document.body.scrollHeight; return lenOfPage;")
十二、chromedriver不加载图片、phantomjs获取动态网页
1、Chromedriver不加载图片设置
# Chromedriver不加载图片 设置chromedriver不加载图片 chrome_opt = webdriver.ChromeOptions() # 实例化 prefs = {"profile.managed_default_content_settings.images":2} # 设置不加载图片参数 chrome_opt.add_experimental_option("prefs", prefs) # 添加进配置中 browser = webdriver.Chrome(executable_path="D:/Temp/chromedriver.exe",chrome_options = chrome_opt) # 不加载图片使用
2、phantomjs获取动态页面
需要下载phantomjs.exe,类似于Chromedriver之类
#phantomjs, *面的浏览器, 多进程情况下phantomjs性能会下降很严重 browser = webdriver.PhantomJS(executable_path="C:/phantomjs-2.1.1-windows/bin/phantomjs.exe") browser.get("https://detail.tmall.com/item.htm?spm=a230r.1.14.3.yYBVG6&id=538286972599&cm_id=140105335569ed55e27b&abbucket=15&sku_properties=10004:709990523;5919063:6536025") t_selector = Selector(text=browser.page_source) print (t_selector.css(".tm-price::text").extract()) print (browser.page_source) # browser.quit()
十三、网页自动截图
# 案例:分别打开我要自学网页面和百度页面,然后进行截图 from selenium import webdriver from time import sleep #加载浏览器驱动 driver=webdriver.Firefox() #打开hao123页面并截图 driver.get("http://www.hao123.com") driver.get_screenshot_as_file(r"E:\Python_script\51zxw.jpg") #打开百度页面并截图 driver.get("http://www.baidu.com") driver.get_screenshot_as_file(r"E:\Python_script\baidu.png") sleep(2) driver.quit()
十四、Cookie处理
from selenium import webdriver driver=webdriver.Chrome() driver.get("http://www.baidu.com/") #获取cookie全部内容 cookie=driver.get_cookies() #打印全部cookile信息 print(cookie) #打印cookie第一组信息 print(cookie[0]) #添加数据到网页cookie driver.add_cookie({'name':'51zxw','value':'www.baidu.com'}) for cookie in driver.get_cookies(): print("%s --- %s" %(cookie['name'],cookie['value'])) driver.quit()
demo:
# 案例:使用Cookie绕过百度验证码自动登录账户 from selenium import webdriver from time import sleep driver=webdriver.Firefox() driver.get("http://www.baidu.com/") #手动添加cookie driver.add_cookie({'name':'BAIDUID','value':'9E4BF1D44014…(根据实际获取值填写)'}) driver.add_cookie({'name':'BDUSS','value':'根据实际抓包获取值填写'}) sleep(2) driver.refresh() sleep(3) driver.quit()
十五、知识点补充-By方式定位
导入:from selenium
.webdriver.common.by import By
- find_element(By.ID,"loginName")
- find_element(By.NAME,"SubjectName")
- find_element(By.CLASS_NAME,"u-btn-levred")
- find_element(By.TAG_NAME,"input")
- find_element(By.LINK_TEXT,"退出")
- find_element(By.PARTIAL_LINK_TEXT,"退")
- find_element(By.XPATH,".//*[@id='Title")
- find_element(By.CSS_SELECTOR,"[type=submit]")
十六、设置ip代理
from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--proxy-server=http://192.168.11.11:80") # 设置ip代理 driver = webdriver.Chrome(executable_path = driver_path) driver.get(url)