Selenium(浏览器自动化测试框架) 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
下载浏览器驱动,Selenium3.x调用浏览器必须有一个webdriver驱动文件
最好下载最新的跟Chrome版本对应上
查看Chorme浏览器版本信息:
1.chromedriver与chrome各版本及下载地址
将chromedriver
的路径拷贝,使用webdriver.Chrome()
方法驱动浏览器的需要这个命令的路径。
XPath Helper可以支持在网页点击元素生成xpath,整个抓取使用了xpath、正则表达式、消息中间件、多线程调度框架的chrome插件。
/ 从根节点选取
// 选取所有的当前节点,不考虑他们的位置
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
例:
/body/div[1] 选取body下的第一个div节点
/body/div[last()] 选取body下最后一个div节点
/body/div[positon()<3] 选取body下前两个div节点
/body/div[@class] 选取body下带有class属性的div节点
# 通配符 *
/div/* 选取div下的所有子节点
/div[@*] 选取所有带属性的div节点
# 功能函数
starts-with //div[starts-with(@id,”ma”)] 选取id值以ma开头的div节点
contains //div[contains(@id,”ma”)] 选取id值包含ma的div节点
and //div[contains(@id,”ma”) and contains(@id,”in”)] 选取id值包含ma和in的div节点
text() //div[contains(text(),”ma”)] 选取节点文本包含ma的div节点
使用//div/p[@title="用户名登录"]
找到页面的 用户名登录的 按钮
通过//form/p/input[@name="userName"]
获得用户名输入框
通过//form/p/input[@name="password"]
获得密码输入框
通过//form/p/input[@type="submit"]
获取登陆提交框
# author: LiuShihao
# data: 2020/12/3 9:55 下午
# youknow: 各位老铁,我的这套代码曾经有人出价三个亿我没有卖,如今拿出来和大家分享,不求别的,只求大家免费的小红心帮忙点一点,这里谢过了。
# desc:
"""
Selenium(浏览器自动化测试框架) 是一个用于Web应用程序测试的工具。
pip3 install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
下载浏览器驱动,Selenium3.x调用浏览器必须有一个webdriver驱动文件
Chrome : https://chromedriver.storage.googleapis.com/index.html?path=2.35/
FileFox:https://github.com/mozilla/geckodriver/releases
Bug : 驱动浏览器是 Chorme显示正受到自动测试软件的控制
"""
from selenium import webdriver
import time
# 驱动文件路径 字母前加r表示raw string,也叫原始字符串常量。一般用在一下两个方面:
# 1、正则表达式
# 用于处理正则表达式时,规避反斜杠的转义
# 2、系统路径
# 如下面的路径,使用r就防止了\t的转义
driverfile_path = r'/Users/LiuShihao/PycharmProjects/SpiderPython/Browser/Baidu/chromedriver'
# 通过用户名登陆
def loginByUsernameAndPwd():
driver.get("https://www.baidu.com/")
# content = driver.page_source
# print("网页内容:", content)
# 使用//a[@name="tj_login"]这种写法虽然在页面可以找到但是 却不可交互 不知道为什么 换下面的写法
# tj_login=driver.find_element_by_xpath('//a[@name="tj_login"]')
tj_login=driver.find_element_by_xpath('//body/div/div/div[@id="u1"]/a')
print("点击登陆按钮")
tj_login.click()
time.sleep(2)
"""
大概意思是程序无法定位到“用户名登录”,
我们可以确定我们写的xpath路径是正确的,
那是为什么呢?原因是程序执行的很快,
在浏览器没加载出“用户名登录”的时候我们程序就开始点击了,
那么我们可以在点击前暂停程序2秒钟等待加载完页面,
"""
usernameLogin=driver.find_element_by_xpath('//div/p[@title="用户名登录"]')
# 获得用户名登陆
# usernameLogin=driver.find_element_by_xpath('//body/div/div[2]/div[2]/div/div/div/div/div/div[3]/p[2]')
usernameLogin.click()
# 获得用户名输入框
driver.find_element_by_xpath('//form/p/input[@name="userName"]').send_keys('百度账号用户名')
# 获得密码输入框
driver.find_element_by_xpath('//form/p/input[@name="password"]').send_keys('百度账号密码')
# 获得登陆按钮
login = driver.find_element_by_xpath('//form/p/input[@type="submit"]')
# 登录
login.click()
def loginByQQ():
# 获取不到元素有可能是因为页面还未加载完成,需要将程序睡眠两秒。
driver.get("https://www.baidu.com/") # //a[@name="tj_login"] 百度页面 登陆按钮
# 获取网页内容Elements
content = driver.page_source
print("网页内容:",content)
login = driver.find_element_by_xpath('//div[@id="u1"]/a')
# 点击登陆按钮
login.click()
time.sleep(2)
# 定位 qq登陆按钮
qq = driver.find_element_by_xpath('//div/ul/li[@class="bd-acc-qzone"]/a')
# 点击qq登陆
qq.click()
time.sleep(2)
# 此行代码用来新窗口
windows = driver.window_handles
driver.switch_to.window(windows[1])# //a[@id="switcher_plogin"]
driver.find_element_by_id('ptlogin_iframe').click()
driver.maximize_window()
# 切换至账户密码框
driver.switch_to.frame('ptlogin_iframe')
# 选择账号密码登陆
driver.find_element_by_id('switcher_plogin').click()
#qq用户
driver.find_element_by_id('u').send_keys('qq账号')
# qq密码
driver.find_element_by_id('p').send_keys('qq密码')
# 登陆
driver.find_element_by_id('login_button').click()
if __name__ == '__main__':
# 不再让Chorme浏览器显示'正受到自动测试软件的控制'
option = webdriver.ChromeOptions()
option.add_experimental_option('useAutomationExtension', False)
option.add_experimental_option('excludeSwitches', ['enable-automation'])
# option.add_argument('disable-infobars');
# 启动浏览器
driver = webdriver.Chrome(executable_path=driverfile_path,options=option)
# 打开百度网址
# driver.get("https://baidu.com")
# 最大化
driver.maximize_window()
# loginByUsernameAndPwd()
loginByQQ()
巨坑!
页面还没有加载完成,程序已经执行了,所以程序获取不到标签!
解决办法:
将程序睡眠两秒
time.sleep(2)
在QQ登陆的页面有一个iframe标签,因为账户输入登陆在一个子iframe里面的,如果直接定位里面的元素是定位不到的,所以需要先切换到这个子iFrame,好像这是一个js框架,也就是切换到这个框架。
自动化测试在一个页面打开一个或多个窗口时,想要定位到其他窗口时,才会用到切换这个框架,为何同一个页面内的元素也需要切换呢? 我的理解是,iframe这个框架与窗口都是一个囊括其他元素的集合或者说模块,里面的东西是被封装的,因此想要定位到里面的元素就需要先切换到这个款架里面,方可定位。
driver.find_element_by_id('switcher_plogin').click()