安装包
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
安装谷歌浏览器和驱动
https://www.google.cn/chrome/
https://googlechromelabs.github.io/chrome-for-testing/
选择当前的版本的浏览器对应的驱动
以前的老版本驱动网址
https://chromedriver.storage.googleapis.com/index.html
安装微软浏览器驱动
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/?form=MA13LH
简单示例打开百度
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# 创建 WebDriver 对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome(service=Service(r'd:\tools\chromedriver.exe'))
"""如果嫌弃不想输入浏览器驱动地址
可以试一下将浏览器驱动放入你运行该程序的python环境中
也就是python.exe的同级目录然后就会变为
wd = webdriver.Chrome()"""
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.baidu.com')
# 程序运行完会自动关闭浏览器,就是很多人说的闪退
# 这里加入等待用户输入,防止闪退
input('等待回车键结束程序')
常用使用方式寻找元素进行操作
from selenium import webdriver
from selenium.webdriver.common.by import By
# 创建 WebDriver 对象
wd = webdriver.Chrome()
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('www.baidu.com')
# 根据id选择元素,返回的就是该元素对应的WebElement对象
element = wd.find_element(By.ID, 'kw') #id查找
element = wd.find_element(By.CLASS_NAME, 'animal') #class查找
element = wd.find_element(By.TAG_NAME, 'div') #元素标签查找
注意:
find_element为只会返回第一个元素
find_elements 返回的是找到的符合条件的所有元素,放在一个列表中返回
另外
WebElement对象 也可以调用 find_elements, find_element 之类的方法
WebDriver对象 选择元素的范围是整个 web页面
例 element = wd.find_element(By.ID, 'kw')
WebElement对象 选择元素的范围是该元素的内部。
例 element.find_elements(By.ID, 'kw2')
xpath选择器
/为绝对路径相当于直接元素 //相当于相对路径相当于跨代元素
elements = driver.find_elements(By.XPATH, "/html/body/div") # 绝对路径
elements = driver.find_elements(By.XPATH, "//div//p") # 相对路径
elements = driver.find_elements(By.XPATH, "//div/*") # 通配符
根据属性选择
[@属性名=‘属性值’]
//*[@id='west'] 选择id为west的元素
//select[@class='single_choice'] 选择所有select元素中class为single_choice的元素
//p[@class="capital huge-city"] 选择多个属性
//*[contains(@style,'color')] 要选择style属性值包含color字符串的页面元素
//*[starts-with(@style,'color')] 要选择style属性值以color字符串开头的页面元素
根据次序选择
某类型第几个子元素
//p[2] p类型第2个的子元素,就是
//div/p[2] 父元素为div中的p类型第2个子元素
//div/*[2] 父元素为div的第2个子元素
//p[last()] p类型倒数第1个子元素
//p[last()-1] p类型倒数第2个子元素
//div/p[last()-2] 父元素为div中p类型倒数第3个子元素
//option[position()<=2] option类型第1到2个子元素
//*[@class='multi_choice']/*[position()<=3] class属性为multi_choice的前3个子元素
//*[@class='multi_choice']/*[position()>=last()-2] class属性为multi_choice的后3个子元素
组选择器
xpath也有组选择, 是用 竖线 隔开多个表达式
//option | //h4 选所有的option元素和所有的h4元素
//*[@class='single_choice'] | //*[@class='multi_choice'] 选所有的 class 为 single_choice 和 class 为 multi_choice 的元素
节点
元素的父节点用 /..
//*[@id='china']/.. 选id为china的节点的父节点
后面兄弟节点用following-sibling::
//*[@class='single_choice']/following-sibling::* 选择 class 为 single_choice 的元素的所有后续兄弟节点
前面兄弟节点,用preceding-sibling::
//*[@class='single_choice']/preceding-sibling::* 选择class为single_choice的元素的所有前面的兄弟节点
//*[@class='single_choice']/preceding-sibling::*[1] 前面最靠近的兄弟节点
//*[@class='single_choice']/preceding-sibling::*[2] 前面第2靠近的兄弟节点
特殊情况
通过xpath选择某个对象里面的子元素
elements = china.find_elements(By.XPATH, '//p')
会打印整个页面所有子元素而不是该china对象的子元素需要修改为,需要在xpath表达式最前面加个点 。
elements = china.find_elements(By.XPATH, './/p')
css选择器
element = wd.find_element(By.CSS_SELECTOR, 'div') #选择tag名为div的元素
element = wd.find_element(By.CSS_SELECTOR, '#searc') # id选择 格式为#加id名
element = wd.find_element(By.CSS_SELECTOR, '.animal') # 类选择 格式为.加类名
css 选择器支持通过任何属性来选择元素,语法是用一个方括号 []
选择 属性href值为 www.baidu.com 的元素
element = wd.find_element(By.CSS_SELECTOR, '[href="www.baidu.com"]')
前面还可以加上标签名的限制,例如:
a[href*="baidu"] #href属性包含了 baidu字符串
a[href^="www"] # href属性以 www开头
a[href$="com"] # href属性以 com 结尾
如果一个元素具有多个属性CSS选择器可以指定选择的元素要同时具有多个属性的限制
例如<div class="misc" ctype="gun">沙漠之鹰</div>
可以这样写 div[class=misc][ctype=gun]
css还支持关系查找
元素1 > 元素2 直接后代 中间 >
元素1 元素2 非直接后代 中间空格
span:nth-child(2) span类型第2个子元素
span:nth-last-child(2) span类型倒数第2个子元素
span:nth-of-type(1) 第1个span类型 的子元素
span:nth-last-of-type(1)倒数第1个span类型 的子元素
span:nth-child(even) span下的偶数子元素奇数为odd
h3 + span h3 后面紧跟着的兄弟节点 span
h3 ~ span h3 后面所有的兄弟节点 span
组查找
同时选择所有class 为 plant 和 class 为 animal 的元素 使用逗号
element = wd.find_element(By.CSS_SELECTOR, '.plant , .animal')
注意别搞混了
选择所有 id 为 t1里面的 span 和 id 为 t1里面的p 元素
#t1 > span , #t1 > p
选择所有id为t1里面的(span和 p元素)
#t1 > span,p
选择框(特殊)
radio
radio框选择选项,直接用WebElement的click方法,模拟用户点击就可以了。
先打印当前选中的老师名字
再选择 小雷老师
<div id="s_radio">
<input type="radio" name="teacher" value="小江老师">小江老师<br>
<input type="radio" name="teacher" value="小雷老师">小雷老师<br>
<input type="radio" name="teacher" value="小凯老师" checked="checked">小凯老师
</div>
对应的代码如下
# 获取当前选中的元素
element = wd.find_element(By.CSS_SELECTOR,
'#s_radio input[name="teacher"]:checked')
print('当前选中的是: ' + element.get_attribute('value'))
# 点选 小雷老师
wd.find_element(By.CSS_SELECTOR,
'#s_radio input[value="小雷老师"]').click()
其中 #s_radio input[name=“teacher”]:checked 里面的 :checked 是CSS伪类选择
表示选择 checked 状态的元素,对 radio 和 checkbox 类型的input有效
checkbox
<div id="s_checkbox">
<input type="checkbox" name="teacher" value="小江老师">小江老师<br>
<input type="checkbox" name="teacher" value="小雷老师">小雷老师<br>
<input type="checkbox" name="teacher" value="小凯老师" checked="checked">小凯老师
</div>
# 先把 已经选中的选项全部点击一下
elements = wd.find_elements(By.CSS_SELECTOR,
'#s_checkbox input[name="teacher"]:checked')
for element in elements:
element.click()
# 再点击 小雷老师
wd.find_element(By.CSS_SELECTOR,
"#s_checkbox input[value='小雷老师']").click()
select
select框是一个新的select标签,对于Select 选择框,Selenium专门提供了一个 Select类进行操作。
Select类 提供了如下的方法
select_by_value根据选项的value属性值选择元素。
比如,下面的HTML,
<option value="foo">Bar</option>
就可以根据 foo 这个值选择该选项
s.select_by_value('foo')
select_by_index 根据选项的次序(从0开始)选择元素
select_by_index(0) ,选择的是 第1个选项
select_by_visible_text根据选项的可见文本选择元素
比如,下面的HTML,
<option value="foo">Bar</option>
就可以根据 Bar 这个内容,选择该选项
s.select_by_visible_text('Bar')
deselect_by_value
根据选项的value属性值去除选中元素
deselect_by_index
根据选项的次序去除选中元素
deselect_by_visible_text
根据选项的可见文本去除选中元素
deselect_all
去除选中所有元素
select单选框
<select id="ss_single">
<option value="小江老师">小江老师</option>
<option value="小雷老师">小雷老师</option>
<option value="小凯老师" selected="selected">小凯老师</option>
</select>
# 导入Select类
from selenium.webdriver.support.ui import Select
# 创建Select对象
select = Select(wd.find_element(By.ID, "ss_single"))
# 通过 Select 对象选中小雷老师
select.select_by_visible_text("小雷老师")
select多选框
用select类的deselect_all方法,清除所有已经选中的选项。
然后再通过select_by_visible_text方法选择小雷老师和小凯老师。
<select id="ss_multi" multiple="">
<option value="小江老师">小江老师</option>
<option value="小雷老师">小雷老师</option>
<option value="小凯老师" selected="selected">小凯老师</option>
</select>
# 导入Select类
from selenium.webdriver.support.ui import Select
# 创建Select对象
select = Select(wd.find_element(By.ID, "ss_multi"))
# 清除所有 已经选中 的选项
select.deselect_all()
# 选择小雷老师 和 小凯老师
select.select_by_visible_text("小雷老师")
select.select_by_visible_text("小凯老师")
隐式等待/全局等待功能
由于网络等因素需要等待元素出现使用此方法
wd.implicitly_wait()
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Chrome()
wd.implicitly_wait(10)
wd.get('www.baidu.com')
....后续读取元素操作....
WebElement对象的常用使用方法
element.click() # 元素点击 常用于按钮键
element.clear() # 清除输入框已有的字符串
element.send_keys('白月黑羽') # 输入新字符串
element.text #获取元素展示在界面上的文本内容
element.get_attribute('class') #获取元素的属性值,示例为获取class属性值
#获取整个元素对应的HTML文本内容,可以使用 element.get_attribute('outerHTML')
#获取某个元素内部的HTML文本内容element.get_attribute('innerHTML')
#获取input输入框里面的输入文本element.get_attribute('value')
#如果元素的文本内容没有展示在界面上尝试使用 element.get_attribute('innerText')或element.get_attribute('textContent')
重点 frame或者窗口切换
在html语法中,frame元素或者iframe元素的内部会包含一个被嵌入的另一份html文档,如果我们要操作被嵌入的html文档中的元素,就必须切换操作范围到被嵌入的文档中
wd.switch_to.frame(frame_reference)
frame_reference 可以是frame元素的属性name或者ID
可以填写 iframe元素的id 'frame1' 或者 name属性值 'innerFrame'。
wd.switch_to.frame('frame1')
wd.switch_to.frame('innerFrame')
切换回外部的html中
wd.switch_to.default_content()
切换回指定窗口
for handle in wd.window_handles:
# 先切换到该窗口
wd.switch_to.window(handle)
# 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口
if '窗口关键词' in wd.title:
# 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,
break
切换回原来窗口(先保存老窗口再切换回来)
# mainWindow变量保存当前窗口的句柄
mainWindow = wd.current_window_handle
#通过前面保存的老窗口的句柄,自己切换到老窗口
wd.switch_to.window(mainWindow)
对话框
弹出的对话框有三种类型,分别是 Alert(警告信息)、confirm(确认信息)和prompt(提示输入)
Alert
Alert弹出框,目的就是显示通知信息,只需用户看完信息后,点击OK(确定)就可以了。
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get('https://cdn2.byhy.net/files/selenium/test4.html')
# --- alert ---
driver.find_element(By.ID, 'b1').click()
# 打印 弹出框 提示信息
print(driver.switch_to.alert.text)
# 点击 OK 按钮
driver.switch_to.alert.accept()
Confirm
Confirm弹出框,主要是让用户确认是否要进行某个操作。Confirm弹出框有两个选择供用户选择,分别是OK和Cancel,分别代表确定和取消操作。
如果我们想点击 OK 按钮如下
driver.switch_to.alert.accept()
如果我们想点击 Cancel 按钮可以用 dismiss方法,如下
driver.switch_to.alert.dismiss()
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get('https://cdn2.byhy.net/files/selenium/test4.html')
# --- confirm ---
driver.find_element(By.ID, 'b2').click()
# 打印 弹出框 提示信息
print(driver.switch_to.alert.text)
# 点击 OK 按钮
driver.switch_to.alert.accept()
driver.find_element(By.ID, 'b2').click()
# 点击 取消 按钮
driver.switch_to.alert.dismiss()
Prompt
Prompt弹出框是需要用户输入一些信息,提交上去
driver.switch_to.alert.send_keys()
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get('https://cdn2.byhy.net/files/selenium/test4.html')
# --- prompt ---
driver.find_element(By.ID, 'b3').click()
# 获取 alert 对象
alert = driver.switch_to.alert
# 打印 弹出框 提示信息
print(alert.text)
# 输入信息,并且点击 OK 按钮 提交
alert.send_keys('web自动化 - selenium')
alert.accept()
# 点击 Cancel 按钮 取消
driver.find_element(By.ID, 'b3').click()
alert = driver.switch_to.alert
alert.dismiss()
其他操作
窗口信息
driver.get_window_size() 获取窗口大小
driver.set_window_size(x, y) 改变窗口大小
driver.title 获取当前窗口标题
driver.current_url 获取当前窗口URL地址
driver.get_screenshot_as_file('1.png') 截屏
上传文件
网站页面上传文件的功能,是通过 type 属性 为 file 的 HTML input 元素实现的。
<input type="file" multiple="multiple">
使用selenium自动化上传文件,我们只需要定位到该input元素,然后通过 send_keys 方法传入要上传的文件路径即可。
# 先定位到上传文件的 input 元素
ele = wd.find_element(By.CSS_SELECTOR, 'input[type=file]')
# 再调用 WebElement 对象的 send_keys 方法
ele.send_keys(r'h:\g02.png')
需要上传多个文件,可以多次调用send_keys
ele = wd.find_element(By.CSS_SELECTOR, 'input[type=file]')
ele.send_keys(r'h:\g01.png')
ele.send_keys(r'h:\g02.png')
文档资源大部分引用来源于b站up主白月黑羽https://www.byhy.net/,详细点的可以去这个网址看