Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏
安装
pip insatll selenium
WebDriver是一个用来进行复杂重复的web自动化测试的工具,可以理解它是谷歌的浏览器的驱动或者插件,自动化selenium提供调用该方法进行自动化的操作
PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的 JavaScript
# 镜像网址:http://npm.taobao.org/mirrors/chromedriver
# pip install selenium
# 1.百度搜索淘宝镜像
# 2.进入搜索结果(点击NPM镜像-NPM下载地址)https://developer.aliyun.com/mirror/NPM?from=tnpm
# 3.选择之后,点击ChromeDriver镜像,和phantomjs镜像
# 4.查看谷歌浏览器版本,右上角三个点(点击)
# 帮助
# 关于谷歌
# 记住谷歌浏览器版本
# 5.在点击进入Chromedriver后,选择版本与谷歌浏览器版本一致或约等于的版本
# 6.点击下载
# 7.解压(获取压缩后的.exe文件)
# 8.将.exe的文件放入python解释器的安装同级目录下(即python.exe的同级目录)
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(‘https://www.csdn.net’)
from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
# 无界面启动,也可以直接设置options.headless=True
option.add_argument("--headless") # 指定无头模式
browser = webdriver.Chrome(options=option)
# 获取浏览器大小
browser.set_window_size(1920, 1080)
# 访问csdn,发送请求
browser.get("https://wwww.baidu.com")
print(browser.page_source)
from selenium import webdriver
# 创建driver对象
driver = webdriver.Chrome()
# 访问的起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
# 将网页生成为图片
driver.save_screenshot("长城.png")
# 根据element内容,id的属性定位
driver.find_element_by_id("kw").send_keys("长城")
driver.find_element_by_id("su").click()
# 获取element的源码内容
driver.page_source
# 打印页面的标题
print(driver.title)
# 获取cookie
driver.get_cookies()
# 退出当前页面
driver.close()
# 退出浏览器
driver.quit()
# 最大化浏览器
driver.maximize_window()
# 刷新
driver.refresh()
# 后退
driver.back()
# 前进
driver.forward()
# 最大化窗口
driver.maximize_window()
# 设置浏览器大小
driver.set_window_size(300,300)
# 设置浏览器位置
driver.set_window_position(300,200)
# 关闭浏览器单个窗口
driver.close()
# 关闭浏览器所有窗口
driver.quit()
from selenium import webdriver
driver = webdriver.Chrome()
# 窗口最大化
driver.maximize_window()
url = 'https://www.baidu.com'
driver.get(url)
"""根据标签属性定位"""
# 根据标签属性id定位
# send_keys() 赋值,传入值,输入值
driver.find_element_by_id('kw').send_keys('哥尔赞')
# 根据标签class属性定位
driver.find_element_by_class_name('s_ipt').send_keys('迪迦')
# 根据标签name属性定位
driver.find_element_by_name('wd').send_keys('金刚')
"""根据xpath语法定位"""
driver.find_element_by_xpath('//*[@id="kw"]').send_keys('迪丽热巴')
"""根据CSS语法定位"""
driver.find_element_by_css_selector('#kw').send_keys('林允')
1. size 返回元素大小
2. text 获取元素的文本
3. title 获取页面title
4. current_url 获取当前页面URL
5. get_attribute("xxx") 获取属性值;xxx:要获取的属性
6. is_display() 判断元素是否可见
7. is_enabled() 判断元素是否可用
提示:
1. size、text、title、current_url:为属性,调用时无括号;如:xxx.size
2. title、current_url:使用浏览器实例化对象直接调用; 如: driver.title
# 获取用户名文本框大小
size=driver.find_element_by_id("userA").size
print('size:',size)
# 获取a标签内容
text=driver.find_element_by_id("fwA").text
print('a标签text:',text)
# 获取title
title=driver.title
print('title:',title)
# 获取当前页面url
url=driver.current_url
print('url:',url)
# 获取a标签href属性值
href=driver.find_element_by_id("fwA").get_attribute("href")
print('href属性值为:',href)
# 判断span是否显示
display=driver.find_element_by_css_selector('span').is_displayed()
print('span标签是否显示:',display)
# 判断取消按钮是否可用
enabled=driver.find_element_by_id('cancelA').is_enabled()
print('取消按钮是否可用:',enabled)
driver.page_source 当前标签页浏览器渲染之后的网页源代码
driver.current_url 当前标签页的url
driver.close() 关闭当前标签页,如果只有一个标签页则关闭整个浏览器
driver.quit() 关闭浏览器
driver.forward() 页面前进
driver.back() 页面后退
driver.screen_shot(img_name) 页面截图
find_element_by_id 返回一个元素
find_element(s)_by_class_name 根据类名获取元素列表
find_element(s)_by_name 根据标签的name属性值返回包含标签对象元素的列表
find_element(s)_by_xpath 返回一个包含元素的列表
find_element(s)_by_link_text 根据连接文本获取元素列表
find_element(s)_by_partial_link_text 根据链接包含的文本获取元素列表
find_element(s)_by_tag_name 根据标签名获取元素列表
find_element(s)_by_css 根据css选择器来获取元素列表
解析:
find_element和find_elements的区别:
多了个s就返回列表,没有s就返回匹配到的第一个标签对象
find_element匹配不到就抛出异常,find_elements匹配不到就返回空列表**
by_link_text和by_partial_link_text的区别:
全部文本和包含某个文本
以上函数的使用方法:
driver.find_element_by_id(‘id_str’)
1. context_click() 右击 --> 此方法模拟鼠标右键点击效果
2. double_click() 双击 --> 此方法模拟双标双击效果
3. drag_and_drop() 拖动 --> 此方法模拟双标拖动效果
4. move_to_element() 悬停 --> 此方法模拟鼠标悬停效果
5. perform() 执行 --> 此方法用来执行以上所有鼠标方法
示例:
1. 导包:from selenium.webdriver.common.action_chains import ActionChains
2. 实例化ActionChains对象:Action=ActionChains(driver)
3. 调用右键方法:element=Action.context_click(username)
4. 执行:element.perform()
示例:
获取文本 element.text
通过定位获取的标签对象的 text 属性,获取文本内容
获取属性值 element.get_attribute(‘属性名’)
通过定位获取的标签对象的 get_attribute 函数,传入属性名,来获取属性的值
from selenium import webdriver
# 创建driver对象
driver = webdriver.Chrome()
# 访问的起始的url地址
start_url = 'https://www.csdn.net/'
# 访问
driver.get(url=start_url)
result = driver.find_elements_by_tag_name('a')
print(result[1].text)
ret = driver.find_elements_by_link_text('收藏')
print(ret[0].get_attribute('href'))
使用: 以豆瓣首页为例:https://www.douban.com/
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.douban.com/")
ret1 = driver.find_element_by_id("anony-nav")
print(ret1)
# 输出为:
ret2 = driver.find_elements_by_id("anony-nav")
print(ret2)
#输出为:[]
ret3 = driver.find_elements_by_xpath("//*[@id='anony-nav']/h1/a")
print(len(ret3))
#输出为:1
ret4 = driver.find_elements_by_tag_name("h1")
print(len(ret4))
#输出为:1
ret5 = driver.find_elements_by_link_text("下载豆瓣 App")
print(len(ret5))
#输出为:1
ret6 = driver.find_elements_by_partial_link_text("豆瓣")
print(len(ret6))
#输出为:28
driver.close()
窗口切换:
获取所有标签页的窗口句柄
利用窗口句柄字切换到句柄指向的标签页
窗口句柄:指的是指向标签页对象的标识
解析:
#1.获取当前所有的标签页的句柄构成的列表
current_windows = driver.window_handles
#2.根据标签页句柄列表索引下标进行切换
driver.switch_to.window(current_windows[0])
from selenium import webdriver
import time
# 创建driver对象
driver = webdriver.Chrome()
# 访问的起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
time.sleep(1)
driver.find_element_by_id('kw').send_keys('python')
time.sleep(1)
driver.find_element_by_id('su').click()
time.sleep(1)
# 通过执行js来新开一个标签页
js = 'window.open("https://www.csdn.net");'
driver.execute_script(js)
time.sleep(1)
# 1.获取所有浏览器窗口
windows = driver.window_handles
# 2.根据窗口索引进行切换
driver.switch_to.window(windows[0])
time.sleep(1)
driver.switch_to.window(windows[1])
iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是driver.switch_to.frame(frame_element)
# 网易邮箱登录
from selenium import webdriver
import time
def login(user, password):
driver = webdriver.Chrome()
driver.get("https://email2.163.com/")
# browser.maximize_window()
driver.switch_to.frame(driver.find_element_by_xpath('//iframe[starts-with(@id,"x-URS")]'))
time.sleep(1)
driver.find_element_by_xpath('//input[@name="email"]').send_keys(user)
driver.find_element_by_xpath('//input[@name="password"]').send_keys(password)
driver.find_element_by_xpath('//*[@id="dologin"]').click()
time.sleep(2)
print(driver.page_source)
driver.save_screenshot("163.png")
time.sleep(3)
# driver.quit()
if __name__ == '__main__':
login('163邮箱帐号', '密码')
**driver.switch_to.default_content() --> 恢复默认页面方法 **
(在frame表单中操作其他页面,必须先回到默认页面,才能进一步操作)
**1. 跳回最外层的页面 driver.switch_to.default_content() – 切换到最外层(对于多层页面,可通过该方法直接切换到最外层) **
2. 跳回上层的页面 driver.switch_to.parent_frame() – 进行向上的单层切换
切换到定位的frame标签嵌套的页面中
driver.switch_to.frame(通过find_element_by函数定位的frame、iframe标签对象)
利用切换标签页的方式切出frame标签
windows = driver.window_handles
driver.switch_to.window(windows[0])
获取cookie
driver.get_cookies() 返回列表,其中包含的是完整的cookie信息,需要转换为字典
字典推导式转换
cookies_dict = {cookie[‘name’]: cookie[‘value’] for cookie in driver.get_cookies()}
删除cookie
删除一条cookie
driver.delete_cookie(‘cookie_name’)
删除所有的cookie
driver.delete_all_cookies()
分类:
1.强制等待
time.sleep()
缺点:不智能,设置的时间太短,元素还没有加载出来,设置的时间太长,浪费时间
2.隐式等待
针对元素定位,隐式等待设置了一个时间,在一段时间内判断元素是否定位成功,如果完成了,就进行下一步
在设置时间内没有定位成功,则会报超时加载
# 隐式等待
from selenium import webdriver
from selenium.webdriver import ChromeOptions
driver = webdriver.Chrome()
# 最多等待你10秒,10秒过后,没有找到就报错
# 一找到,就接着往下执行
driver.implicitly_wait(10)
driver.get('https://www.csdn.net')
3.显示等待
明确等待某一个元素,超时则报异常
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.csdn.net')
# 通过文本名称进行定位
driver.find_element_by_link_text('人工智能').click()
WebDriverWait(driver, 20, 0.5).until(EC.presence_of_all_elements_located((By.LINK_TEXT, '地图')))
"""
参数20表示最长等待20s
参数0.5表示0.5s检查一次规定的标签书否存在
EC.presence_of_all_elements_located((By.LINK_TEXT, '地图')):通过文本内容定位标签
每0.5s一次检查,通过链接文本内容定位标签是否存在,如果存在就向下继续执行,如果不存在20s上限就报错
"""
手动实现页面等待
原理:
利用强制等待和显示等待的思路来手动实现
不停的判断或有次数限制的判断某一个标签对象是否加载完毕(是否存在)
执行js的方法:driver.execute_script(js)
使用代理ip的方法
实例化配置对象
配置对象添加使用代理ip的命令
实例化带有配置对象的driver对象
from selenium import webdriver
# 1.创建一个配置对象
options = webdriver.ChromeOptions()
# 2.使用代理
options.add_argument('--proxy-server=http://192.168.129.130')
# 3.创建driver对象
driver = webdriver.Chrome(options=options)
# 4.设置起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
替换user-agent的方法
实例化配置对象
配置对象添加替换UA的命令
实例化带有配置对象的driver对象
from selenium import webdriver
from fake_useragent import UserAgent
ua = UserAgent()
# 1.创建一个配置对象
options = webdriver.ChromeOptions()
# 2.使用代理
options.add_argument('--user--agent={}'.format(ua.chrome))
# ua = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'
# options.add_argument('user-agent' + ua)
# 3.创建driver对象
driver = webdriver.Chrome(options=options)
# 4.设置起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
print(driver.title)
from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions() #实例化一个ChromeOptions对象
option.add_experimental_option('excludeSwitches', ['enable-automation']) #以键值对的形式加入参数
bro = webdriver.Chrome(executable_path='./chromedriver.exe',options=option) #在调用浏览器驱动时传入option参数就能实现undefined
第二种(常用)
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ })
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
# 禁止弹窗
prefs = {
'profile.default_content_setting_values':
{
'notifications': 2
}
}
# 禁止弹窗加入
chrome_options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get(url)
# 就可以访问无通知弹窗的浏览器了
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.maximize_window() # 设置浏览器大小:全屏
browser.get('https://www.baidu.com')
# 定位输入框
input_box = browser.find_element_by_id('kw')
try:
# 输入内容:selenium
input_box.send_keys('selenium')
print('搜索关键词:selenium')
except Exception as e:
print('fail')
# 输出内容:搜索关键词:selenium
# 定位搜索按钮
button = browser.find_element_by_id('su')
try:
# 点击搜索按钮
button.click()
print('成功搜索')
except Exception as e:
print('fail搜索')
# 输出内容:成功搜索
# clear():清空输入框
try:
input_box.clear()
print('成功清空输入框')
except Exception as e:
print('fail清空输入框')
# 输出内容:成功清空输入框
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.maximize_window() # 设置浏览器大小:全屏
browser.get('https://www.baidu.com')
# 定位输入框
input_box = browser.find_element_by_id('kw')
# 输入关键词:selenium
input_box.send_keys('selenium')
# 模拟回车操作
try:
input_box.submit()
print('成功回车')
except Exception as e:
print('fail')
# 输出内容:成功回车
# 导入需要的模块Select()类是用来管理下拉框的
from selenium import webdriver
from selenium.webdriver.support.select import Select
import time
# 创建浏览器对象
driver = webdriver.Chrome()
driver.maximize_window()
# 访问贴吧的高级搜素
driver.get('https://tieba.baidu.com/f/search/adv')
# 定位到下拉框元素
el_select = driver.find_element_by_name('rn')
# 创建一个下拉框对象
xialakuang = Select(el_select)
# 三种方法选择下拉框选项
# 第一、通过选项的索引来选定选项(索引从0开始算)
xialakuang.select_by_index(0)
time.sleep(1)
xialakuang.select_by_index(2)
time.sleep(1)
xialakuang.select_by_index(1)
time.sleep(1)
# 第二种方法:通过option标签的属性值选择
xialakuang.select_by_value('20')
time.sleep(1)
xialakuang.select_by_value('10')
time.sleep(1)
xialakuang.select_by_value('30')
time.sleep(1)
# 第三种:通过文本选择(下拉框的值)
xialakuang.select_by_visible_text('每页显示20条')
time.sleep(1)
xialakuang.select_by_visible_text('每页显示10条')
time.sleep(1)
xialakuang.select_by_visible_text('每页显示30条')
time.sleep(1)
# 打印选择的文本
# 查看第一个已选(若有多个已选则打印第一个,只有一个已选则打印一个)
print(xialakuang.first_selected_option.text)
# 打印所有已选的选项的文本
yixuan = xialakuang.all_selected_options
for i in yixuan:
print('已选',i.text)
# 打印是否是多选
print(xialakuang.is_multiple)
# 打印所有选项(包括已选和未选的)
m_list = xialakuang.options
for a in m_list:
print('选项',a.text)
# # 关闭浏览器
# driver.quit()
from selenium.webdriver.common.action_chains import ActionChains
# 定位到需要悬停的标签
move = driver.find_element_by_id("xpath语法")
# 开始悬停
ActionChains(self.driver).move_to_element(move).perform()