总目录
- 一、selenium是什么?
- 二、selenium自动化环境安装
- 三、简单示例
- 四、选择元素的基本方法
- 1、根据 id属性 选择元素。
- 2、根据 class属性 选择元素
- 3、根据 tag名 选择元素
- 五、等待界面元素出现
- 六、操控元素
- 七、CSS表达式选择元素
- 八、选择语法联合使用
- 九、组选择
- 十、按次序选择子节点
- 十一、兄弟节点选择
一、selenium是什么?
- Selenium 是一个开源的自动化测试工具,专门用于Web应用程序的测试。它允许测试脚本(包括python、Java、JavaScript等)直接在浏览器中运行,模拟真实用户的操作。
- Selenium 的自动化原理是这样的:
二、selenium自动化环境安装
1、安装客户端库(不同的编程语言选择不同的selenium客户端库,这里我们用的是python语言)
- 打开pycharm,点击左下角的
python3.11,再点击interpreter Settings... - 在左边找到python interpreter,再点击右边的加号
- 在搜索框中,搜索selenium,点击install Package,等待下载就好了。
2、安装主流浏览器和浏览器驱动(Chrome、Edge、Firefox等)
我用的是自带的浏览器edge,点击下方链接可以下载edge浏览器驱动:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/?form=MA13LH
下载完成之后,将压缩包解压到无中文无空格的目录下,将浏览器驱动所在目录添加到环境变量的path中。
三、简单示例
fromseleniumimportwebdriver# 从库中导入相应的包webdriver=webdriver.Edge()# 创建浏览器驱动对象webdriver.get("http://www.baidu.com")# 浏览器驱动打开百度网页input()# 程序运行完成会自动关闭浏览器,加一个输入代码可以看到被打开的网页四、选择元素的基本方法
web界面自动化,先要定位元素,才能操作元素。
特别注意:Selenium 升级到版本 4 以后, 下面这种 find_element_by* 方法都作为过期不赞成的写法
# 初始化代码 ....wd.find_element_by_id('username').send_keys('byhy')wd.find_element_by_class_name('password').send_keys('sdfsdf')wd.find_element_by_tag_name('input').send_keys('sdfsdf')wd.find_element_by_css_selector('button[type=submit]').click()运行会有告警,所以现在都要写成下面这种格式
fromselenium.webdriver.common.byimportBy# 初始化代码 ....wd.find_element(By.ID,'username').send_keys('byhy')wd.find_element(By.CLASS_NAME,'password').send_keys('sdfsdf')wd.find_element(By.TAG_NAME,'input').send_keys('sdfsdf')wd.find_element(By.CSS_SELECTOR,'button[type=submit]').click()1、根据 id属性 选择元素。
示例网址:https://www.byhy.net/cdn2/files/selenium/stock1.html
示例代码:
fromseleniumimportwebdriver# 从库中导入相应的包fromselenium.webdriver.common.byimportBy# 导入bywebdriver=webdriver.Edge()# 创建浏览器驱动对象webdriver.get("https://www.byhy.net/cdn2/files/selenium/stock1.html")# 浏览器驱动打开网页webdriver.find_element(By.ID,'kw').send_keys('股份\n')# 定位股份名称输入框,输入股份二字,回车webdriver.find_element(By.ID,'suggestion').send_keys("666")# 定位建议输入框,输入666webdriver.find_element(By.ID,'submit-suggestion').click()# 定位提交按钮,点击提交input()效果图:
2、根据 class属性 选择元素
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
""" 通过class属性 来定位元素 """fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy webdriver=webdriver.Edge()# 创建浏览器驱动webdriver.get("https://www.byhy.net/cdn2/files/selenium/sample1.html")# 打开相应的网址elements=webdriver.find_elements(By.CLASS_NAME,'plant')# 通过class属性定位植物elements1=webdriver.find_elements(By.CLASS_NAME,'animal')# 通过class属性定位所有的动物forelementinelements:# 以下都是循环输入文本内容print(element.text)print("=============")forelement1inelements1:print(element1.text)注意:
1、find_elements返回的是找到的符合条件的 所有 元素 (这里有3个元素), 放在一个 列表 中返回。
2、而如果我们使用webdriver.find_element(注意少了一个s) 方法, 就只会返回 第一个 元素。
多个class类型的使用:
学生张三 可以定义有 多个 类型: 中国人 和 学生 , 中国人 和 学生 都是 张三 的 类型。
元素也可以有 多个class类型 ,多个class类型的值之间用 空格 隔开,比如<span class="chinese student">张三</span>
注意,这里 span元素 有两个class属性,分别 是 chinese 和 student, 而不是一个 名为 chinese student 的属性。
我们要用代码选择这个元素,可以指定任意一个class 属性值,都可以选择到这个元素,如下
element=wd.find_elements(By.CLASS_NAME,'chinese')或者
element=wd.find_elements(By.CLASS_NAME,'student')而不能这样写
element=wd.find_elements(By.CLASS_NAME,'chinese student')3、根据 tag名 选择元素
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy webdriver=webdriver.Edge()webdriver.get("https://www.byhy.net/cdn2/files/selenium/sample1.html")elements=webdriver.find_elements(By.TAG_NAME,'span')elements1=webdriver.find_elements(By.TAG_NAME,'div')forelementinelements:print(element.text)print("-------")forelement1inelements1:print(element1.text)find_element 和 find_elements 的区别:
使用 find_elements 选择的是符合条件的 所有 元素, 如果没有符合条件的元素, 返回空列表。
使用 find_element 选择的是符合条件的 第一个 元素, 如果没有符合条件的元素, 抛出 NoSuchElementException 异常。
五、等待界面元素出现
在我们进行网页操作的时候, 有的元素内容不是可以立即出现的, 可能会等待一段时间。
Selenium提供了一个更合理的解决方案,是这样的:
当发现元素没有找到的时候, 并不立即返回 找不到元素的错误。
而是周期性(每隔半秒钟)重新寻找该元素,直到该元素找到,
或者超出指定最大等待时长,这时才 抛出异常(如果是 find_elements 之类的方法, 则是返回空列表)。
Selenium 的 Webdriver 对象 有个方法叫 implicitly_wait ,可以称之为隐式等待,或者全局等待。
该方法接受一个参数, 用来指定 最大等待时长。
如果我们 加入如下代码:
webdriver.implicitly_wait(10)那么后续所有的find_element或者find_elements之类的方法调用 都会采用上面的策略:
如果找不到元素, 每隔半秒钟再去界面上查看一次, 直到找到该元素, 或者 过了10秒 最大时长。
示例网址:https://www.byhy.net/cdn2/files/selenium/stock1.html
示例代码:
fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy webdriver=webdriver.Edge()webdriver.implicitly_wait(10)webdriver.get("https://www.byhy.net/cdn2/files/selenium/stock1.html")webdriver.find_element(By.ID,'kw').send_keys('国投\n')element=webdriver.find_element(By.ID,'1')print(element.text)webdriver.quit()六、操控元素
操控元素通常包含:点击元素;在元素中输入字符串;获取元素包含的信息,比如文本内容,元素的属性。
1、点击元素
当我们调用webElement对象的click方法去点击元素的时候,浏览器接收到自动化命令,点击的是该元素的中心点位置。
2、输入框
输入字符串也非常简单,就是调用元素webElement对象的send_keys方法。
如果我们要 把输入框中已经有的内容清除掉,可以使用WebElement对象的clear方法。
示例网址:https://www.byhy.net/cdn2/files/selenium/test3.html
示例代码:
element=wd.find_element(By.ID,"input1")element.clear()# 清除输入框已有的字符串element.send_keys('白月黑羽')# 输入新字符串3、获取元素文本信息
(1)通过WebElement对象的 text 属性,可以获取元素展示在界面上的文本内容。
element=wd.find_element(By.ID,'animal')print(element.text)补充:
通过WebElement对象的 text 属性,可以获取元素展示在界面上的文本内容。
但是,有时候,元素的文本内容没有展示在界面上,或者没有完全完全展示在界面上。 这时,用WebElement对象的text属性,获取文本内容,就会有问题。
出现这种情况,可以尝试使用element.get_attribute('innerText'),或者element.get_attribute('textContent')
使用 innerText 和 textContent 的区别是,前者只显示元素可见文本内容,后者显示所有内容(包括display属性为none的部分)
(2)获取元素属性
通过WebElement对象的 get_attribute 方法来获取元素的属性值
比如要获取元素属性class的值,就可以使用element.get_attribute('class')
示例网址:https://www.byhy.net/cdn2/files/selenium/stock1.html
示例代码:
fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy# 获取元素属性webdriver=webdriver.Edge()webdriver.get("https://www.byhy.net/cdn2/files/selenium/stock1.html")element=webdriver.find_element(By.ID,'1')print(element.get_attribute('class'))# 打印出来的是:result-itemelement1=webdriver.find_element(By.ID,'suggestion')print(element1.get_attribute('placeholder'))# 打印出来的是:一句话建议(3)获取整个元素对应的HTML
要获取整个元素对应的HTML文本内容,可以使用element.get_attribute('outerHTML')
如果,只是想获取某个元素内部的HTML文本内容,可以使用element.get_attribute('innerHTML')
示例网址:https://www.byhy.net/cdn2/files/selenium/stock1.html
示例代码:
(4)获取输入框里面的文字
对于input输入框的元素,要获取里面的输入文本,用text属性是不行的,这时可以使用element.get_attribute('value')
示例网址:https://www.byhy.net/cdn2/files/selenium/stock1.html
示例代码:
fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy# 获取输入框的值webdriver=webdriver.Edge()webdriver.get("https://www.byhy.net/cdn2/files/selenium/stock1.html")element=webdriver.find_element(By.ID,"kw")element.send_keys("四川路桥")print(element.get_attribute('value'))七、CSS表达式选择元素
通过 CSS Selector 选择单个元素的方法是:
find_element(By.CSS_SELECTOR,CSS Selector参数)选择所有元素的方法是:
find_elements(By.CSS_SELECTOR,CSS Selector参数)(1)根据class属性选择元素的语法是在class值前面加上一个点:.class值
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
(2)根据id属性 选择元素的语法是在id号前面加上一个井号:#id值
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
(3)选择 子元素 和 后代元素
- 如果 元素2 是 元素1 的 直接子元素, CSS Selector 选择子元素的语法是这样的:
元素1>元素2中间用一个大于号 (我们可以理解为箭头号)
注意:最终选择的元素是 元素2, 并且要求这个 元素2 是 元素1 的直接子元素
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
- 如果 元素2 是 元素1 的 后代元素, CSS Selector 选择后代元素的语法是这样的:
元素1元素2中间是一个或者多个空格隔开
最终选择的元素是 元素2 , 并且要求这个 元素2 是 元素1 的后代元素。
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
(4)根据属性选择
id、class 都是web元素的 属性 ,因为它们是很常用的属性,所以css选择器专门提供了根据 id、class 选择的语法。
那么其他的属性呢?
css 选择器支持通过任何属性来选择元素,语法是用一个方括号 [] 。
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy webdriver=webdriver.Edge()webdriver.get("https://www.byhy.net/cdn2/files/selenium/sample1.html")element=webdriver.find_element(By.CSS_SELECTOR,'.footer2 [href]')print(element.get_attribute('outerHTML'))- CSS 还可以选择 属性值包含 某个字符串的元素
比如, 要选择a节点,里面的href属性包含了 miitbeian 字符串,就可以这样写:a[href*="miitbeian"] - 还可以 选择 属性值以某个字符串 开头的元素
比如, 要选择a节点,里面的href属性 以 http 开头,就可以这样写:a[href^="http"] - 还可以 选择 属性值以某个字符串 结尾的元素
比如, 要选择a节点,里面的href属性以 gov.cn 结尾,就可以这样写 :a[href$="gov.cn"] - 如果一个元素具有多个属性
<div class="misc" ctype="gun">沙漠之鹰</div>
CSS 选择器 可以指定 选择的元素要 同时具有多个属性的限制,像这样div[class=misc][ctype=gun]
八、选择语法联合使用
CSS selector的另一个强大之处在于: 选择语法 可以联合使用
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
九、组选择
如果我们要同时选择所有的class为plant和class为animal的元素。怎么定位?
这种情况,css选择器可以使用逗号,称之为 组选择器,像这样
.plant,.animal示例网址:https://www.byhy.net/cdn2/files/selenium/sample1.html
示例代码:
再比如,我们要同时选择所有tag名为div的元素 和 id为BYHY的元素,就可以像这样写
div,#BYHY十、按次序选择子节点
(1)父元素的第n个子节点
我们可以指定选择的元素是父元素的第几个子节点,使用nth-child
示例网址:[https://www.byhy.net/cdn2/files/selenium/sample1b.html](https://www.byhy.net/cdn2/files/selenium/sample 1b.html)
示例代码:(选择第二个子元素,并且是span类型)
如果你不加节点类型限制,直接这样写:nth-child(2)
就是选择所有位置为第2个的所有元素,不管是什么类型。
(2)父元素的倒数第n个子节点
也可以说,选择的是父元素的倒数第几个子节点,使用nth-last-child
比如:
p:nth-last-child(1)# 就是选择第倒数第1个子元素,并且是p元素。示例网址:https://www.byhy.net/cdn2/files/selenium/sample1b.html
示例代码:
(3)父元素的第几个某类型的子节点
我们可以指定选择的元素 是父元素的第几个某类型的子节点,使用nth-of-type
比如,我们要选择 唐诗 和宋词 的第一个 作者,选择的是 第1个span类型 的子元素,所以也可以这样写span:nth-of-type(1)
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1b.html
示例代码:
(4)父元素的倒数第几个某类型的子节点
选择父元素的倒数第几个某类型的子节点,使用nth-last-of-type,像这样p:nth-last-of-type(2)
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1b.html
示例代码:
(5)奇数节点和偶数节点
如果要选择的是父元素的偶数节点,使用nth-child(even),比如
p:nth-child(even)如果要选择的是父元素的奇数节点,使用nth-child(odd)
p:nth-child(odd)示例网址:https://www.byhy.net/cdn2/files/selenium/sample1b.html
示例代码:
十一、兄弟节点选择
(1)相邻兄弟节点选择
我们要选择 唐诗 和宋词 的第一个 作者
还有一种思考方法,就是选择 h3 后面紧跟着的兄弟节点 span。
这就是一种 相邻兄弟 关系,可以这样写h3 + span
表示元素 紧跟关系的 是加号
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1b.html
示例代码:
(2)后续所有兄弟节点选择
如果要选择是 选择 h3 后面所有的兄弟节点 span,可以这样写h3 ~ span
示例网址:https://www.byhy.net/cdn2/files/selenium/sample1b.html
示例代码: