selenium中文文档:https://python-selenium-zh.readthedocs.io/zh_CN/latest/
selenium英文文档:https://selenium-python.readthedocs.io/
selenium是一个web自动化测试工具,它支持多种浏览器:ie、ff、safari、opera、chrome,我目前使用比较多的就是chrome,selenium与chrome组合也是真的好用,当然有些兼容性不好的网站,也需要考虑使用IE或360等一些第三方浏览器,我最近遇到的一个项目就是网站不兼容google,必须考虑使用360浏览器(这个我也还在研究中)
环境配置
- python我使用的是3.7,通过Anaconda进行安装的
- 浏览器:查看google版本(chrome://version),然后在还需要下载与之对应版本的chromedriver
- selenium的安装:
浏览器基本操作
启动浏览器以及一些常见的设置
# encoding: utf-8
from selenium import webdriver
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe' # chromedriver.exe存放的位置
#chromeOptions 是一个配置 chrome 启动是属性的类
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('lang=zh_CN.UTF-8') # 设置默认编码
chrome_options.add_argument("window-size=1366,768") # 浏览器窗口大小设置
#chrome_options.add_argument('--headless') # 增加无界面选项
chrome_options.add_argument('--no-sandbox') # 非沙盒模式运行
chrome_options.add_argument('--disable-dev-shm-usage') # 解决报错
prefs = {
"profile.managed_default_content_settings.images": 2, # 禁用图片加载
"download.default_directory": "D:/", # 设置chrome的下载路径
}
chrome_options.add_experimental_option("prefs", prefs)
#driver = webdriver.Chrome(chrome_driver, chrome_options=chrome_options)
# 启动IE,我使用IE加载url的时候会提示Can not connect to the Service
#driver = webdriver.Ie('C:/Program Files (x86)/Internet Explorer/iexplore.exe')
#driver = webdriver.Firefox('火狐安装位置') # 启动火狐
# 启动360浏览器, 要注意下载360对应的chromedriver
chrome_options.binary_location = r'D:/Program Files (x86)/WeChat/360se6/Application/360se.exe'
driver = webdriver.Chrome(chrome_driver, chrome_options=chrome_options)
driver.get('https://www.baidu.com/')
driver.quit()
selenium的三种等待方式
有时下一步的操作会依赖上一步的结果或内容,上一步操作成功后才能进行下一步操作,这时我们需要加上等待操作,等到上一步完成了才能进行下一步操作:
- 等待方式一:time.sleep(xx),强制等待,不管是否处理/加载完,程序都必须等待xx秒
# encoding: utf-8
import time
from selenium import webdriver
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe' # chromedriver.exe存放的位置
driver = webdriver.Chrome(chrome_driver)
driver.get('https://www.baidu.com/')
time.sleep(3)
driver.quit()
- 等待方式二:implicitly_wait(X),隐式等待,X是最长等待时间,在X时间内网页加载完毕,则进行下一步,否则一直等到时间结束,然后执行下一步。隐式等待有一个缺点就是程序会一直等待整个页面加载完成,才会执行下一步,但有时候页面想要的元素早已经加载完毕,只因为个别元素没有加载完毕,而不能进行下一步操作。
# encoding: utf-8
from selenium import webdriver
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe'
driver = webdriver.Chrome(chrome_driver)
driver.implicitly_wait(30)
driver.get('https://www.baidu.com/')
driver.quit()
- 等待方式三:显示等待,WebDriverWait配合该类的until()和until_not()方法,可以根据判断条件进行灵活地等待。它的主要思想是:程序每隔一段时间去检测一下条件是否成立,成立则执行下一步,否则继续等待直到超时,然后抛出异常。
# encoding: utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe'
driver = webdriver.Chrome(chrome_driver)
driver.get('https://www.baidu.com/')
try:
WebDriverWait(driver,30).until(EC.presence_of_element_located((By.ID, 'kw')))
print('加载完成')
except Exception as e:
print('加载超时')
driver.quit()
expected_conditions
类提供的预期条件判断的方法
方法 | 说明 |
title_is | 判断当前页面的 title 是否完全等于(==)预期字符串,返回布尔值 |
title_contains | 判断当前页面的 title 是否包含预期字符串,返回布尔值 |
| 判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见 |
visibility_of_element_located | 判断元素是否可见(可见代表元素非隐藏,并且元素宽和高都不等于 0) |
visibility_of | 同上一方法,只是上一方法参数为locator,这个方法参数是 定位后的元素 |
presence_of_all_elements_located | 判断是否至少有 1 个元素存在于 dom 树中。举例:如果页面上有 n 个元素的 class 都是’wp’,那么只要有 1 个元素存在,这个方法就返回 True |
text_to_be_present_in_element | 判断某个元素中的 text 是否 包含 了预期的字符串 |
text_to_be_present_in_element_value | 判断某个元素中的 value 属性是否包含 了预期的字符串 |
frame_to_be_available_and_switch_to_it | 判断该 frame 是否可以 switch进去,如果可以的话,返回 True 并且 switch 进去,否则返回 False |
invisibility_of_element_located | 判断某个元素中是否不存在于dom树或不可见 |
element_to_be_clickable | 判断某个元素中是否可见并且可点击 |
staleness_of | 等某个元素从 dom 树中移除,注意,这个方法也是返回 True或 False |
element_selection_state_to_be | 判断某个元素的选中状态是否符合预期 |
element_located_selection_state_to_be | 跟上面的方法作用一样,只是上面的方法传入定位到的 element,而这个方法传入 locator |
alert_is_present | 判断页面上是否存在 alert |
selenium中selenium.webdriver.common.by
之By的用法
By是selenium中内置的一个class,在这个class中有各种方法来定位元素,所支持的定位器的分类如下:
方法 | 说明 | 举例 |
By.ID | id属性定位 | find_element(By.ID,“id”) |
By.NAME | name属性定位 | find_element(By.NAME,“name”) |
By.CLASS_NAME | classname属性定位 | find_element(By.CLASS_NAME,“claname”) |
By.LINK_TEXT | a标签文本属性定位 | find_element(By.LINK_TEXT,“text”) |
By.PARTIAL_LINK_TEXT | a标签部分文本属性定位 | find_element(By.PARTIAL_LINK_TEXT,“partailtext”) |
By.TAG_NAME | 标签名定位 | find_elemnt(By.TAG_NAME,“input”) |
By.XPATH | xpath路径定位 | find_element(By.XPATH,“//div[@name=‘name’]”) |
By.CSS_SELECTOR | css选择器定位 | find_element(By.CSS_SELECTOR,“#id”) |
selenium的八种元素定位方法
- id定位:find_element_by_id()
- name定位:find_element_by_name()
- class定位:find_element_by_class_name()
- tag定位:find_element_by_tag_name()
- link定位:find_element_by_link_text()
- partial_link定位:find_element_by_partial_link_text()
- xpath定位:find_element_by_xpath()
- CSS定位:find_element_by_css_selector()
# encoding: utf-8
from selenium import webdriver
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe'
driver = webdriver.Chrome(chrome_driver)
driver.get('https://www.baidu.com/')
#通过id方式定位
driver.find_element_by_id("kw").send_keys("selenium")
#通过name方式定位
driver.find_element_by_name("wd").send_keys("selenium")
#通过tag name方式定位
driver.find_element_by_tag_name("input").send_keys("selenium")
#通过class name方式定位
driver.find_element_by_class_name("s_ipt").send_keys("selenium")
#通过CSS方式定位
driver.find_element_by_css_selector("#kw").send_keys("selenium")
#通过xpath方式定位
driver.find_element_by_xpath("//input[@id='kw']").send_keys("selenium")
driver.find_element_by_class_name("s_btn").click()
driver.quit()
get_attribute获取元素的属性
# encoding: utf-8
from selenium import webdriver
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe'
driver = webdriver.Chrome(chrome_driver)
driver.get('https://www.baidu.com/')
element = driver.find_element_by_id("su")
print(element.get_attribute('value'))
# 获取元素标签的内容
print(element.get_attribute('textContent'))
# # 获取元素内的全部HTML
print(element.get_attribute('innerHTML'))
# # 获取包含选中元素的HTML
print(element.get_attribute('outerHTML'))
# 获取该元素的标签类型
print(element.tag_name)
driver.quit()
键盘事件
要想调用键盘按键操作需要引入 keys 包:
from selenium.webdriver.common.keys import Keys通过 send_keys()调用按键:
- send_keys(Keys.TAB) :制表键(Tab)
- send_keys(Keys.ENTER) :回车键(Enter)
- send_keys(Keys.BACK_SPACE):删除键(BackSpace)
- send_keys(Keys.SPACE):空格键(Space)
- send_keys(Keys.ESCAPE):回退键(Esc)
- 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)
- send_keys(Keys.F1):键盘 F1……
send_keys(Keys.F12):键盘 F12
# encoding: utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe'
driver = webdriver.Chrome(chrome_driver)
driver.get('https://www.baidu.com/')
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("kw").send_keys(Keys.ENTER)
# 前两句也可以这样组合使用
# driver.find_element_by_id("kw").send_keys("selenium", Keys.ENTER)
driver.quit()
鼠标事件
鼠标事件一般包括鼠标右键、双击、拖动、移动鼠标到某个元素上等等。
引用方法:from selenium.webdriver.common.action_chains import ActionChains
ActionChains 常用方法:
perform() 执行所有ActionChains 中存储的行为;
context_click() 右击;
double_click() 双击;
drag_and_drop() 拖动;
move_to_element() 鼠标悬停。
# encoding: utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe'
driver = webdriver.Chrome(chrome_driver)
driver.get('https://www.baidu.com/')
driver.find_element_by_id("kw").send_keys("selenium")
element = driver.find_element_by_id("su")
ActionChains(driver).click(element).perform()
ActionChains(driver).context_click(element).perform() # 右击
driver.quit()
iframe、new window、alert
- iframe是内嵌的网页元素,也可以说是内嵌的框架
# encoding: utf-8
from selenium import webdriver
chrome_driver = 'D:/opt/chromedriver/chromedriver.exe'
driver = webdriver.Chrome(chrome_driver)
driver.get('https://mail.163.com/')
# 切换到iframe 这里可以用之前讲的八种定位方法先进行定位,再进行切换
iframe = driver.find_elements_by_tag_name('iframe')[0]
driver.switch_to_frame(iframe)
driver.find_element_by_name('email').send_keys('aaaa')
driver.find_element_by_name('password').send_keys('aaaa')
driver.quit()
- new window
curHandle = driver.current_window_handle #获取当前窗口句柄
allHandle = driver.window_handles #获取所有聚丙
"""循环判断,只要不是当前窗口句柄,那么一定就是新弹出来的窗口,这个很好理解。"""
flag = False
for h in allHandle:
if h != curHandle:
driver.switch_to.window(h) #切换句柄,到新弹出的窗口
break
'''
这里可以进行新窗口中的一些操作
'''
# 操作完后,想回到之前的句柄
driver.switch_to.window(curHandle)
- alert
alert = driver.switch_to.alert # 切换到弹窗
print(alert.text) # 弹窗内容
alert.accept() # 确认
alert.dimiss() # 取消
反扒
- 如何突破网站对selenium的屏蔽
- google headless被反扒,linux使用pyvirtualdisplay(虚拟界面)