目录
- 常用类与方法
- 选择器
- Keys
- 鼠标相关事件
- EC
常用类与方法
import time
from selenium import webdriver #驱动浏览器
from selenium.webdriver import ActionChains # 鼠标的相关操作,例如滑动验证
from selenium.webdriver.common.by import By # 选择器,以什么方式选择标签元素
from selenium.webdriver.common.keys import Keys # 键盘相关
from selenium.webdriver.support import expected_conditions as EC #各种判断,
from selenium.webdriver.support.wait import WebDriverWait # 等待事件,可以与EC连用
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# driver.find_element() # 定位标签
# print("获取的title", driver.title) #获取当前页面的title
# driver.close() #关闭当前窗口
# driver.quit()#退出浏览器驱动,关闭所有关联窗口
# print("获取当前页面的内容", driver.page_source) # 获取页面的内容,即html页面
# driver.set_window_size(800, 600) # 设置浏览器的宽800px,高600px
# print("获取浏览器窗口大小", driver.get_window_size()) # 获取浏览器窗口的大小
# driver.save_screenshot("a.png") # 保存当前url页面屏幕截图,保存图片的类型必须是.png,命名a.png的图片
# driver.refresh()# 刷新
# driver.back() # 后退
# driver.forward()# 前进
# driver.execute_script("alert(\'xxxoo\');") #执行js代码
# time.sleep(3)
# driver.get_cookies() # 获取cookies
# driver.current_url # 获取当前windows的url
# driver.current_window_handle # 获取当前窗口对象
常用选择器
1、根据id定位
2、根据class定位
3、根据tag name定位
4、根据超链接定位
4.1、绝对定位
4.2、模糊定位
5、根据xpath定位,根据dom树来定位,每个标签在dom树中都有自己的节点
6、根据css selecter(样式选择器定位),非常强大
7、定位input框,根据name属性定位
8、by选择器,封装了上面几种定位形式
补充:每种定位方式都有复数形式
常用选择器
driver.find_element_by_id("")
driver.find_elements_by_id("") # 复数形式以列表返回
driver.find_element_by_class_name("")
driver.find_elements_by_class_name("")
driver.find_element_by_name("")
driver.find_elements_by_name("")
driver.find_element_by_tag_name("")
driver.find_elements_by_tag_name("")
webdriver的基本操作
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = \'tian\' __data__ = \'2021/2/24 17:06\' import time from selenium import webdriver driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(5) driver.get("https://pythonav.com/login/") try: # 获取标签对象 # 打印id=id_username标签的对象 # input_obj = driver.find_element_by_id("id_username") # print(input_obj,type(input_obj)) # 对象<class \'selenium.webdriver.remote.webelement.WebElement\'> # 获取class=login标签所有文本内容 # login_obj = driver.find_element_by_class_name("login") # print("获取class_name=login标签的文本\n",login_obj.text) # 定位到id=id_username的input框,然后输入测试人员,最后打印输入的测试人员 # input_boj=driver.find_element_by_id("id_username") # input_boj.send_keys("测试人员") # print(input_boj.get_attribute("value")) # 清空文本框中输入的内容 # input_obj = driver.find_element_by_id("id_username") # input_obj.send_keys("测试人员") # time.sleep(2) # input_obj.clear() # 获取input框的属性 input_obj = driver.find_element_by_id("id_username") time.sleep(2) print(input_obj.get_attribute("class")) # 获取input框元素里面的class属性值 print(input_obj.get_property("name")) # # get_property()获取值和get_attribute()一样 # 获取标签的css样式 # 获取标签样式的高 print(input_obj.value_of_css_property("height")) # 获取标签样式的颜色 print(input_obj.value_of_css_property("color")) # 验证码图片大小 print(driver.find_element_by_id("image_code").size) except Exception as error: print("报错信息:{0}".format(error)) finally: time.sleep(10) driver.quit()
键盘事件
"""
键盘的操作:
复制/粘贴
全选
回车
"""
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys # 键盘事件
driver = webdriver.Chrome()
driver.get("https://pythonav.com/login/")
obj_d = driver.find_element_by_id("id_username")
obj_d.send_keys("test")
# 全选
obj_d.send_keys(Keys.CONTROL, "a")
time.sleep(2)
# 复制
obj_d.send_keys(Keys.CONTROL, "c")
# 粘贴到密码框
time.sleep(1)
driver.find_element_by_id("id_password").send_keys(Keys.CONTROL, "v")
# 回车
driver.find_element_by_id("id_password").send_keys(Keys.ENTER)
time.sleep(10)
driver.quit()
常用元素定位
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://pythonav.com/login/")
try:
# id定位
# driver.find_element_by_id("id_username").send_keys("嬴政大帅哥")
# class属性定位
# 例如:class="form-control",class属性会存在多个,默认定位到第一个
# driver.find_element_by_class_name("form-control").send_keys("嬴政大帅哥")
# class属性定位,有多个时取第2个,即密码文本框
# input_list = driver.find_elements_by_class_name("form-control")
# print(input_list)
# input_list[1].send_keys("嬴政大帅哥")
# tag name定位即根据标签名
# 标签名会存在很多个,需要自己去前端代码中算需要的目标排在第几个位置
# 默认是拿前端代码中的第一个
# print(driver.find_element_by_tag_name("input").get_property("value"))
# name 属性定位
# 保证标签对象有name属性才能定位。
# driver.find_element_by_name("username").send_keys("嬴政大帅哥")
# link text定位,只针对a标签
# 绝对定位,完全匹配text值
# driver.find_element_by_link_text("首页").click() # 必须完全匹配,否则报错。
# 模糊定位,只要text中包含关键字即可。
# driver.find_element_by_partial_link_text("首页").click()
# xpath定位
# driver.find_element_by_xpath(\'//*[@id="id_username"]\').send_keys("嬴政大帅哥")
# css selector选择器(常用)
# 可以根据:
# 1、根据id
# 2、根据class
# 3、tag name
# 4、支持匹配符,例如:^,$,*
# css selector中id
# driver.find_element_by_css_selector("#id_username").send_keys("嬴政大帅哥")
# 标签名+id
# driver.find_element_by_css_selector("input#id_username").send_keys("嬴政大帅哥")
# css selector中class
# driver.find_element_by_css_selector(".form-control").send_keys("嬴政大帅哥")
# 标签名+class属性值
# driver.find_element_by_css_selector("input.form-control").send_keys("嬴政大帅哥")
# 根据标签名,获取该标签名中name属性的值
# print(driver.find_element_by_css_selector("input").get_attribute("name"))
# 通配符^ 以什么开头
# driver.find_element_by_css_selector("input[id=id_username]").send_keys("嬴政大帅哥")
# 匹配id_pas开头的id值
# driver.find_element_by_css_selector("input[id ^=id_pas]").send_keys("嬴政大帅哥")
# 通配符$ 以什么结尾
# 匹配以word结尾
# driver.find_element_by_css_selector("input[id $=word]").send_keys("嬴政大帅哥")
# 通配符* 包含的关系
# driver.find_element_by_css_selector("input[id *=word]").send_keys("嬴政大帅哥")
# by选择器
# By.XPATH
# By.LINK_TEXT
# By.CSS_SELECTOR
# By.TAG_NAME
# By.ID
# 根据By.ID定位
driver.find_element(By.ID, "id_username").send_keys("嬴政大帅哥")
except Exception as e:
print(e)
finally:
time.sleep(3)
driver.quit()
上传文件
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://127.0.0.1:8002/upload/1") # 文件上传的url
#send_keys()参数为文件路径
driver.find_element_by_id("alaxFile").send_keys(r"D:\pythonscript\selenium_stendert\note\geckodriver.log")
driver.find_element_by_id("ajaxBtn").click() # 点击上传按钮
driver.quit()
滚动条操作
相对移动
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(time_to_wait=10)
driver.get("https://www.cnblogs.com/")
time.sleep(3)
driver.execute_script("window.scrollBy(0, 700)") # 相对移动,从当前位置移动700像素
time.sleep(3)
driver.execute_script("window.scrollBy(0, 700)") # 相对移动,从当前位置移动700像素,即:上次移动700+本次的700=1400像素
time.sleep(3)
driver.quit()
移动到底部/顶部
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(time_to_wait=10)
driver.get("https://www.cnblogs.com/")
time.sleep(3)
# 获取当前窗口对象
element = driver.find_element_by_tag_name(\'body\')
# 从顶部下拉到底部
driver.execute_script("arguments[0].scrollIntoView(false);", element) # 默认为true
time.sleep(3)
# driver.execute_script("window.scrollTo(0, document.body.scrollHeight)") # 使用window对象
# 从底部拉到顶部
driver.execute_script("arguments[0].scrollIntoView(true);", element)
time.sleep(3)
driver.quit()
等待机制
作用:用于网络延迟严重场景,避免代码执行较快,标签还没有加载完成就对该标签进行操作,出现报错问题。
为了避免报错,就需要使用等待机制。
selenium中,有三种等待机制:
1、显示等待
当有需要等待的标签时,才去使用等待。
2、隐式等待,在浏览器对象创建之初,就为这个对象添加一个【被动】,即隐式等待,当遇到查找标签的时候,就自动的触发被动也就是隐式等待。
隐式等待的意思就是:用不用都给加上。
3、python的休眠机制,time.sleep(),强制睡眠。
常用【隐式等待】
# 隐式等待
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(time_to_wait=10) #写在开头 只要有找标签的动作,就加等待
try:
driver.get("https://www.baidu.com")
driver.find_element_by_id("kw").send_keys("听雨危楼-cnblogs") # 找该标签会触发等待
driver.find_element_by_id("su").click() # 找该标签会触发等待
driver.find_element_by_link_text("听雨危楼 - 博客园").click() # 找该标签会触发等待
time.sleep(3)
except Exception as er:
print(er)
finally:
driver.quit()
显示等待(写代码比较多,了解即可)
# 显示等待
import time
from selenium.webdriver.support.wait import WebDriverWait # 显示等待
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
driver = webdriver.Chrome()
wait = WebDriverWait(driver=driver, timeout=10, poll_frequency=0.5) # 在超时时间之内,每0.5秒检查一次指定标签渲染是否成功
try:
driver.get("https://www.baidu.com")
driver.find_element_by_id("kw").send_keys("听雨危楼-cnblogs")
driver.find_element_by_id("su").click()
wait.until(EC.visibility_of_element_located((By.LINK_TEXT, "听雨危楼 - 博客园")), "没有找到").click() # 需要找到元素,并且该元素可见except Exception as er:
print(er)
finally:
driver.quit()
常用鼠标事件
import time from selenium import webdriver from selenium.webdriver import ActionChains driver = webdriver.Chrome() driver.get("http://sahitest.com/demo/clicks.htm") time.sleep(1) # 鼠标左键双击 # ActionChains(driver).double_click(driver.find_element_by_xpath("/html/body/form/input[2]")).perform() # perform是执行 # 鼠标右击单击 # ActionChains(driver).context_click(driver.find_element_by_xpath("/html/body/form/input[4]")).perform() # 悬浮 # driver.get("http://www.cnblogs.com/Neeo/articles/11002003.html") # ActionChains(driver).move_to_element(driver.find_element_by_id("cb_post_title_url")).perform() # 拖拽 driver.get("https://www.jq22.com/demo/pintu20151229/") time.sleep(2) driver.find_element_by_id("start").click() strat = driver.find_element_by_xpath(\'//*[@id="container"]/div[1]\') endt = driver.find_element_by_xpath(\'//*[@id="container"]/div[25]\') ActionChains(driver).drag_and_drop(strat, endt).perform() time.sleep(3) driver.quit()
窗口切换
一般的窗口切换就是浏览器打开多个窗口,使用selenium在多个窗口中相互切换。除此之外,还会遇到iframe窗口,这种相当于大盒子中嵌套小盒子,对于这种窗口切换,重点就是进入某个盒子,退出某个盒子。知道当前在哪个盒子中,就好搞操作了。
重点:
-
driver.switch_to系列,切换窗口,包括三个常用的方法:
- switch_to.window,切换窗口,替换switch_to_window
- switch_to.frame,进入iframe,替换switch_to_frame
- switch_to.default_content,退出iframe,替换原方法switch_to_default_content
- switch_to.window,切换窗口,替换switch_to_window
- window_handles,窗口数组
根据这两个方法组合,就达到切换窗口的目的了。我们来演示一个,从百度入口输入关键字并且点击某个结果(因为点击某个链接,会在新的窗口中打开),然后再切换回来。
代码如下:
例1:切换标签页:
import time from selenium import webdriver from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.implicitly_wait(20) try: # 发请求 driver.get("https://www.baidu.com") # 定位标签并深入值然后点击 driver.find_element_by_id("kw").send_keys("听雨危楼-cnblogs") time.sleep(1) driver.find_element_by_id("su").click() # 在新窗口中,点击结果标签 wait.until(EC.presence_of_element_located((By.LINK_TEXT, \'听雨危楼 - 博客园\'))).click() # 所有打开的窗口都存在这个数组中 print(driver.window_handles) # 根据数组下标索引切换窗口 time.sleep(3) driver.switch_to_window(driver.window_handles[1]) time.sleep(3) driver.switch_to_window(driver.window_handles[0]) except Exception as er: print(er) finally: # 关闭浏览器 time.sleep(3) driver.quit()
iframe窗口切换
iframe记住两个方法:
- switch_to.frame(iframe),进入窗口
- switch_to.default_content(),退出窗口
我们完成一个使用selenium自动发163邮件的程序。
import time from selenium import webdriver driver = webdriver.Chrome()
drrver.implicityl_wait(20) try: # 切换iframe # https://email.163.com/ driver.get("https://email.163.com/") div = driver.find_element_by_id("urs163Area") iframe = div.find_element_by_tag_name("iframe") driver.switch_to.frame(iframe) # 切换到iframe里面 driver.find_element_by_name("email").send_keys("tian") driver.switch_to.default_content() # 切出去iframe except Exception as er: print(er) finally: # 关闭浏览器 time.sleep(3) driver.quit()
例2:切换ifram和鼠标拖拽
import time from selenium import webdriver driver = webdriver.Chrome() driver.implicitly_wait(20) try: # 切换iframe和拖拽 driver.get("https://jqueryui.com/droppable/") driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) # 页面只有1个iframe,就这样写 t1 = driver.find_element_by_id("draggable") t2 = driver.find_element_by_id("droppable") from selenium.webdriver import ActionChains ActionChains(driver).drag_and_drop(t1, t2).perform() time.sleep(2) driver.switch_to.default_content() #切换出来 driver.find_element_by_link_text("jQuery UI").click() except Exception as er: print(er) finally: # 关闭浏览器 time.sleep(3) driver.quit()
截图
1、截取当前可见页面的图
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
time.sleep(2)
# 截取当前可见页面的图
driver.save_screenshot("a.png") # 保存当前url页面屏幕截图,保存图片的类型必须是.png,命名a.png的图片
driver.quit()
2、截取指定区域图
方法1:利用--->from PIL import Image
需求:只截取验证码图片的大小,保存当前目录下命名b.png
步骤:先截取当前可见区域的图片,保存在当前目录下命名a.png
利用你Image再次截取a.png中验证码区域的图片,保存在当前目录下命名b.png
import time from PIL import Image # pillow模块这样导入 from selenium import webdriver full_img = "./a.png" code_img = "./b.png" driver = webdriver.Chrome() driver.implicitly_wait(10) driver.maximize_window() driver.get("https://pythonav.com/login/") driver.save_screenshot(full_img) # 截取可见区域的图片 # 需求:只截取验证码图片的大小,保存当前目录下命名b.png imageCode = driver.find_element_by_id("image_code") print(imageCode.size) # {\'height\': 30, \'width\': 120} left = imageCode.location[\'x\'] * 1.28 # 执行当前代码电脑的屏幕的缩放x top = imageCode.location[\'y\'] * 1.26 # 执行当前代码电脑的屏幕的缩放y right = imageCode.size[\'width\'] + left height = imageCode.size[\'height\'] + top temp = Image.open(full_img) temp = temp.crop((left, top, right, height)) temp.save((code_img)) time.sleep(5) driver.quit()
PS:截图不准确时,可以查看自己当前电脑的屏幕缩放然后在x和y处进行相乘。或者将当前电脑的屏幕缩放调整100%即可。
方法2:
需求和方法1是一样:
截取图片验证码,保存在当前目录命名为b.png
import time from selenium import webdriver full_img = "./a.png" code_img = "./b.png" driver = webdriver.Chrome() driver.implicitly_wait(10) driver.maximize_window() driver.get("https://pythonav.com/login/") driver.save_screenshot(full_img) # 截取可见区域的图片 imageCode = driver.find_element_by_id("image_code") imageCode.screenshot(code_img) time.sleep(5) driver.quit()
3、截取整个网页的图
需求:原因:当网页内容过多时,需要通过滚动条下拉查看。如何截取整个网页的图片呢?
通过无头浏览器PhantomJS来截取:
# 网页需要下拉浏览器滚动条才能查看完毕,截取整个长网页的图 from selenium import webdriver driver = webdriver.PhantomJS(executable_path=r"C:\Python\Python37\Scripts\phantomjs\bin\phantomjs.exe") # 无头浏览器安装路径 driver.implicitly_wait(time_to_wait=10) driver.get("https://pythonav.com/project/detail/1/") driver.save_screenshot("a.png") driver.quit()