安装
- 安装依赖包
pip install selenium
-
selenium
是配合浏览器一起使用,所以需要下载浏览器对应版本的驱动文件webdriver
- 检测安装是否成功
# 普通启动
from selenium import webdriver
# 1. 实例化一个浏览器
browser = webdriver.Chrome("./chromedriver") # 参数为驱动路径
browser.get("http://www.baidu.com/") # 驱动浏览器访问百度
browser.page_source # 获取当前浏览器的html
browser.quit() # 退出实例化的浏览器
元素定位方式
- 单元素提取-返回元素对象
browser.find_element_by_id("id") # 通过id定位
browser.find_element_by_name("name") # 通过name定位
browser.find_element_by_link_text("link") # 通过链接文本定位
browser.find_element_by_partial_link_text("link") # 通过链接文本定位
browser.find_element_by_class_name("class_name") # 通过classname定位
browser.find_element_by_tag_name("input") # 通过tag标签定位
browser.find_element_by_xpath("//input[@id='kw']") # 通过xpath定位
browser.find_element_by_css_selector("#kw") # 通过CSS方式定位
注意:如果是多元素提取-返回包含多元素对象的列表,可以通过数组index
取出对应的元素对象
元素对象操作方法
browser.find_element_by_name("name").click() # 点击对象
browser.find_element_by_name("name").send_keys("keyword") # 模拟键盘输入
browser.find_element_by_name("name").clear() # 清除对象的内容
browser.find_element_by_name("name").submit() # 提交对象的内容
browser.find_element_by_name("name").text() # 获取元素的文本信息
browser.find_element_by_name("name").context_click() # 右键单击
browser.find_element_by_name("name").double_click() # 双击
browser.find_element_by_name("name").is_displayed() # 是否用户可见
页面对象的操作方法
browser.maximize_window() # 浏览器最大化
browser.minimize_window() # 浏览器最小化
browser.set_window_size(480, 800) # 自定义浏览器窗口大小
browser.forword() # 浏览器前进
browser.back() # 浏览器后退
browser.close() # 关闭浏览器当前窗口
browser.quit() # 退出浏览器驱动并关闭所有窗口
browser.refresh() # 刷新当前页
browser.page_source # 获取当前页html
browser.title # 获取当前页标题
browser.url # 获取当前页url
ifame
browser.switch_to_frame("f1") # 找到 f1 iframe
browser.switch_to_window("f1") # 找到内嵌窗口 f1
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
多窗口切换
driver.get("http://example.com") # 打开一个窗口
now_handle = drvier.current_window_handle # 获取当前窗口句柄
driver.find_element_by_name('example').click() # 点击某个元素打开新的窗口(target="_black"的元素)
all_handle = drvier.window_handles # 获取所有窗口句柄
drvier.switch_to.window(now_handle) # 切换为第一窗口
driver.close() # 关闭当前窗口
通过input上传附件
self.browser.find_element_by_xpath('//input[@class="file-selector-file"]').send_keys("/Users/mac/Documents/myspider/selenium_spider/test.mp4") # 必须要用绝对路径
操作cookies
browser.get_cookie("name") # 根据name获取单个cookie
browser.get_cookies() # 获取所有cookie
browser.delete_all_cookies() # 删除所有cookies
browser.delete_cookie("name") # 根据name删除对应cookie
browser.add_cookie({"k1": "v1", "k2": "v2"}) # 设置cookies
获取截屏
browser.get_screenshot_as_file("/usr/download/down_image.png") # 保存当前窗口截图
browser.get_screenshot_as_png() # 获取当前png截图的二进制字符串
等待方式
- 强制等待
time.sleep(10) # 强制程序休眠10s
-
隐式等待
全局设置一个隐式等待时间,等待对象为整个页面,判断依据是:在规定时长内加载完整个页面的所有元素。等待对象是:页面所有元素
driver.implicitly_wait(10) # seconds,隐式等待,参数为最长等待时间(s)。页面全部加载完成才会执行下一步操作
-
显式等待
显式等待指定某个条件,然后设置最长等待时间。如果在这个时间内指定的元素元素达到指定条件,就继续执行。等待对象是:指定元素
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Chrome()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
wait
模块的WebDriverWait
类是显性等待类,参数如下:
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
这里需要特别注意的是until
或until_not
中的可执行方法method参数,很多人传入了WebElement对象,如下:
WebDriverWait(driver, 10).until(driver.find_element_by_id('kw')) # 错误
这是错误的用法,这里的参数一定要是可以调用的,即这个对象一定有 call()
方法,否则会抛出异常:TypeError: 'xxx' object is not callable
, 在这里,你可以用selenium
提供的expected_conditions
模块中的各种条件,也可以用WebElement
的 is_displayed()
、is_enabled()
、is_selected()
方法,或者用自己封装的方法都可以。
WebDriverWait(browser, 30).until(EC.title_is("百度一下,你就知道")) # 等待,直到标题是百度一下,或超时
WebDriverWait(browser, 30).until(EC.title_contains("百度")) # 等待,直到标题包含百度,或超时
WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.ID, "id"))) # 等待,直到Dom中存在该id
WebDriverWait(browser, 30).until(EC.visibility_of_element_located((By.ID, "id"))) # 等待,直到Dom中存在该id并且可见
WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))) # 等待,直到该元素是可点击的
WebDriverWait(browser, 30).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'.main'),'enable')) # 判断.main中是否包含enable字符串,返回布尔值
WebDriverWait(browser, 30).until(EC.staleness_of(driver.find_element(By.ID,'id'))) # 等待,直到id从dom中移除
expected_conditions模块
expected_conditions
是selenium
的一个模块,其中包含一系列可用于判断的条件,所有17个condition
,与until
、until_not
组合能够实现很多判断,如果能自己灵活封装,将会大大提高脚本的稳定性。
selenium.webdriver.support.expected_conditions(模块)
这两个条件类验证title,验证传入的参数title是否等于或包含于driver.title
title_is
title_contains
这两个人条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, 'kw')
顾名思义,一个只要一个符合条件的元素加载出来就通过;另一个必须所有符合条件的元素都加载出来才行
presence_of_element_located
presence_of_all_elements_located
这三个条件验证元素是否可见,前两个传入参数是元组类型的locator,第三个传入WebElement
第一个和第三个其实质是一样的
visibility_of_element_located
invisibility_of_element_located
visibility_of
这两个人条件判断某段文本是否出现在某元素中,一个判断元素的text,一个判断元素的value
text_to_be_present_in_element
text_to_be_present_in_element_value
这个条件判断frame是否可切入,可传入locator元组或者直接传入定位方式:id、name、index或WebElement
frame_to_be_available_and_switch_to_it
这个条件判断是否有alert出现
alert_is_present
这个条件判断元素是否可点击,传入locator
element_to_be_clickable
这四个条件判断元素是否被选中,第一个条件传入WebElement对象,第二个传入locator元组
第三个传入WebElement对象以及状态,相等返回True,否则返回False
第四个传入locator以及状态,相等返回True,否则返回False
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
最后一个条件判断一个元素是否仍在DOM中,传入WebElement对象,可以判断页面是否刷新了
staleness_of
鼠标操作
鼠标操作包含在ActionChains类
中,操作方法如下:
-
context_click(elem)
右击鼠标点击元素elem
,另存为等行为 -
double_click(elem)
双击鼠标点击元素elem
,地图web可实现放大功能 -
drag_and_drop(source,target)
拖动鼠标,源元素按下左键移动至目标元素释放 -
move_to_element(elem)
鼠标移动到一个元素上 -
click_and_hold(elem)
按下鼠标左键在一个元素上 -
perform()
在通过调用该函数执行ActionChains
中存储行为
鼠标操作示例代码
from selenium.webdriver.common.action_chains import ActionChains
el = driver.find_element_by_name('tj_trnews') # 目标元素
ActionChains(driver).context_click(el).perform() # 右击目标元素
ActionChains(driver).double_click(el).perform() # 双击目标元素
source = driver.find_element_by_id('lg') # 目标元素原始位置
target = driver.find_element_by_id('kw') # 拖动的目标位置
ActionChains(driver).drag_and_drop(source, target).perform() # 拖动元素
ActionChains(driver).move_to_element(el).perform() # 鼠标移动的目标元素上
ActionChains(driver).click_and_hold(el).perform() # 移动到目标元素按下鼠标左键
键盘操作
在webdriver
的Keys
类中提供了键盘所有的按键操作,当然也包括一些常见的组合键操作如Ctrl+A(全选)、Ctrl+C(复制)、Ctrl+V(粘贴)。
-
send_keys(Keys.ENTER)
按下回车键 -
send_keys(Keys.TAB)
按下Tab制表键 -
send_keys(Keys.SPACE)
按下空格键space -
send_keys(Kyes.ESCAPE)
按下回退键Esc -
send_keys(Keys.BACK_SPACE)
按下删除键BackSpace -
send_keys(Keys.SHIFT)
按下shift键 -
send_keys(Keys.CONTROL)
按下Ctrl键 -
send_keys(Keys.ARROW_DOWN)
按下鼠标光标向下按键 -
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
键盘操作的代码示例
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
#输入框输入内容
elem = driver.find_element_by_id("kw")
elem.send_keys("Eastmount CSDN")
time.sleep(3)
#删除一个字符CSDN 回退键
elem.send_keys(Keys.BACK_SPACE)
elem.send_keys(Keys.BACK_SPACE)
elem.send_keys(Keys.BACK_SPACE)
elem.send_keys(Keys.BACK_SPACE)
time.sleep(3)
#输入空格+"博客"
elem.send_keys(Keys.SPACE)
elem.send_keys(u"博客")
time.sleep(3)
#ctrl+a 全选输入框内容
elem.send_keys(Keys.CONTROL,'a')
time.sleep(3)
#ctrl+x 剪切输入框内容
elem.send_keys(Keys.CONTROL,'x')
time.sleep(3)
#输入框重新输入搜索
elem.send_keys(Keys.CONTROL,'v')
time.sleep(3)
#通过回车键替代点击操作
driver.find_element_by_id("su").send_keys(Keys.ENTER)
time.sleep(3)
driver.quit()
其他
获取窗口信息
browser.get_window_rect() # 获取当前窗口xy坐标及当前窗口的高度和宽度
browser.get_window_position(windowHandle="current") # 获取当前窗口的x,y坐标
browser.get_window_size(windowHandle="current") # 获取当前窗口的高度和宽度
执行js代码
browser.execute_async_script(script, *args) # 在当前的window/frame中异步执行JS代码
browser.execute_script(script, *args) # 在当前的window/frame中同步执行JS代码
script: JS代码(str)
*args: 要传入js的参数(iterable)
网友评论