目录
- 简介
- 安装及入门
- 元素定位
- 通过浏览器来快速定位元素(不需要自己写CSS选择器和Xpath路径)
- 使用CSS选择器来定位元素
- id选择器;
- 类选择器;
- 标签选择器;
- 其他选择器:
- 选中元素后的常用操作
- 浏览器窗口切换
- 常见问题
- 动态id
- 内嵌网页iframe
- 点击速度过快
简介
selenium是一个用以操作浏览器的库,常被应用于自动化测试和爬虫。
先把相关的文档放上来:https://selenium-python.readthedocs.io/
因为最近使用这个模块比较多,所以分享其中的一些经验给大家。
安装及入门
模块的安装就不赘述了,但安装完模块以后需要同时安装对应浏览器的驱动,并放到python的文件目录下,才能正常的打开浏览器。
具体驱动的下载在上面的文档中可以找到。
元素定位
selenium通过正确打开浏览器并成功打开对应网址之后,就可以进行对浏览器的操作了。
from selenium import webdriver
browser = webdriver.Chrome() #打开浏览器
browser.get('https://www.baidu.com/') #在浏览器中新开一个页面
浏览器中有各种各样的元素,我们需要通过selenium来实现点击、输入或者获取文本信息的功能,就需要首先定位到相关的元素;selenium提供了很多的元素定位的方法:
# selenium提供的元素定位的方法
## CSS选择器 相关的方法
browser.find_element_by_css_selector(selector) #匹配符合css选择器条件的元素
browser.find_element_by_class_name(name) #匹配class属性值元素
browser.find_element_by_id(id) #匹配id属性值的元素
browser.find_element_by_link_text(text) #完全匹配提供text的a元素
browser.find_element_by_partial_link_text(text) #包含提供的text的a元素
browser.find_element_by_name(name) #匹配name属性值的元素
browser.find_element_by_tag_name(name) #匹配标签name的元素(大小写无关,a匹配'a'和'A',div则匹配所有div元素)
## xpath 相关的方法
browser.find_element(s)_by_xpath() #匹配符合xpath路径的元素
每一个元素匹配的方法,都有find_element和find_elements的两个版本;
- 对于find_element版本,会返回符合匹配条件的第一个元素;
- 如果匹配不到元素,则会报错NoSuchElementException: Message: no such element;
- 如果输入的选择器有误,则会报错 InvalidSelectorException: Message: invalid selector ;
- 对于find_elements版本,会返回 装有所有符合匹配条件的元素 的列表;
- 如果匹配不到元素,则会返回一个空列表[],而不会报错,这里与find_element是不同的;
- 如果输入的选择器有误,则会报错 InvalidSelectorException: Message: invalid selector ;
通过浏览器来快速定位元素(不需要自己写CSS选择器和Xpath路径)
如果觉得定位元素太过复杂,就可以借助浏览器来获得帮助。
对着需要定位的元素点击 右键 --> 审查元素 -->选中元素对应html代码的左边的三个点
点击之后 --> Copy --> Copy selector或Copy Xpath
之后相应的CSS选择器或Xpath路径就已经复制到粘贴板上,将相应的CSS选择器复制到相应的函数中即可:
browser.find_element_by_css_selector("粘贴板上的CSS选择器")
browser.find_element_by_xpath("粘贴板上的Xpath路径")
如果运行之后显示选择器无效,可以尝试编辑一下选择器的内容,删除某个节点内容等,这很可能是版本不同而引起的。
使用CSS选择器来定位元素
前端知识预备:
- html 超文本标记语言,用于搭建网页结构,一个html通常由许多个元素组成,而一个元素又通常由成对的标签组成,例如div元素包括:开始标签<div> + 元素内容 + 结束标签</div>;
- CSS(Cascading Style Sheet , 层叠样式表),用于修饰网页结构,是一组格式设置规则,用于设置web页面的外观;
- 所以CSS需要修饰不同的元素,就需要首先选中不同的元素,而CSS用于选中元素的方法,就是CSS选择器;
- 通过F12来查看网页的源代码,或者对准需要定位的元素 点右键-->审查元素 就可以看到元素的具体信息(这里的具体信息包括元素名称、元素属性)。
- 常见的CSS选择器有 id选择器、类选择器、标签选择器、相邻选择器、多元素选择器、后代选择器、子元素选择器、属性选择器;
id选择器;
- 使用场景:id的名称不会出现多次,id表示唯一,网页中有一个唯一的元素需要修饰
- 对应符号:#
- 使用示例:
<div id="u1001">content</div>
- CSS选择器:
#u1001{
/* CSS代码 */
}
- selenium定位方法:
browser.find_element_by_css_selector("#u1001") 匹配符合css选择器条件的元素
browser.find_element_by_id("u1001") 匹配id属性值的元素
类选择器;
- 使用场景:有多个元素需要设置成同一个元素,则可以将这多个元素的class属性设置成同一名称,再对该.classname来设置样式
- 对应符号: .
- 使用示例:
<div class="item">content1</div>
<div class="item">content2</div>
<div class="item">content3</div>
- CSS选择器:
.item{
/* CSS代码 */
}
- selenium定位方法:
browser.find_element_by_css_selector(".item") 匹配符合css选择器条件的元素
browser.find_element_by_class_name("item") 匹配class属性值元素
标签选择器;
- 使用场景:将同一种标签,设置成同一种样式,例如将所有的p段落标签设置成同一种样式
- 对应符号: 无
- 使用示例:
<ul>
<li>content1</li>
<li>content2</li>
<li>content3</li>
<li>content4</li>
</ul>
- CSS选择器:
li{
/* CSS代码 */
}
- selenium定位方法:
browser.find_element_by_css_selector("li") 匹配符合css选择器条件的元素
browser.find_element_by_tag_name("li")
其他选择器:
1.相邻选择器
a. --> 对应的符号是 加号 +
b.用于选择某个元素后面相邻的元素
c.具体:
.box+p{
/* CSS代码 */
/* 这就选中了class="box"后面相邻的p元素 */
}
browser.find_element_by_css_selector(".box+p")
2.多元素选择器/组合选择器
a. --> 对应的符号是 逗号 ,
b.就逗号隔开多个元素,具体:
.box1,.box2,.box3{
/* CSS代码 */
/* 同时选中了class=box1或class=box2或class=box3的元素 */
}
.box1,p{
/* CSS代码 */
/* 同时选中了class=box1或元素标签为p的元素 */
}
browser.find_element_by_css_selector(".box1,.box2,.box3")
browser.find_element_by_css_selector(".box1,p")
3.后代选择器
a. --> 对应的符号是 空格 " "
b.后代指的是子元素,也同时可以是子子元素,以此类推
c.具体示例:
.box p{
/* CSS代码 */
/* 这就选中了.box 后代中所有的p元素,但并不选中.box元素 */
}
browser.find_element_by_css_selector(".box p")
4.子元素选择器
a. --> 对应的符号是 大于号 >
b.与后代类似,但不包含 子子元素 及 以后的
c.具体示例:
.box>p{
/* CSS代码 */
/* 这就选中了.box 元素的子元素(仅仅一代)中所有的p元素,但不选中.box元素 */
}
browser.find_element_by_css_selector(".box>p")
5.属性选择器
a. --> 对应的符号 双边框 [所选择属性名] // [属性名=属性值]同时指定属性及属性值
b.每个标签都可以有属性,例如 id属性、class属性、name属性、type属性、value属性等
属性选择器就可以选中,具有某个属性的元素
c.具体示例:
input[name]{
/* CSS代码 */
/* 这就选中了具有name属性的所有imput元素,无论这个name属性的值是什么 */
}
input[name=password]{
/* CSS代码 */
/* 这就选中了具有name属性的属性值为password的所有imput元素 */
}
input[name^=u]{
/* CSS代码 */
/* 这就选中了具有name属性的属性值为u开头的所有imput元素 */
}
input[name$=d]{
/* CSS代码 */
/* 这就选中了具有name属性的属性值为d结尾的所有imput元素 */
}
browser.find_element_by_css_selector("input[name]")
browser.find_element_by_css_selector("input[name=password]")
browser.find_element_by_css_selector("input[name^=u]")
browser.find_element_by_css_selector("input[name$=d]")
注:如果选中的class属性中,有指定多个属性,即class="c1 c2",就需要a[class^=c1]来选中元素
d.可以同时有多个选择条件
选中元素后的常用操作
- element.click() 点击
- send_keys('北京') 发送内容;这里可以发送回车 不过需要先导入from selenium.webdriver.common.keys import Keys,再send_keys(Keys.ENTER)
- element.get_attribute('href') 可以获取元素的href属性值,也可以获取其他属性,传入其他属性名即可
- element.text 可以查看元素的文本内容;如果网页中明明可以看到内容,但element.text却为空值,则可以用element.is_display()来测试,如果返回False,则元素文本被指定为隐藏,单单用.text无法获取
- 如果文本被隐藏了,可以尝试用element.get_attribute(A) A = textContent或innerText或innerHTML
浏览器窗口切换
- browser.get(url)默认是在原来窗口打开一个网页,会覆盖原来的网页
- 通过窗口的句柄来操作不同窗口的元素 句柄handle
- 执行下面的两个语句就可以打开一个新的页面
js='window.open("xxx.xxxx.com 可以为空字符串,空字符串则打开空的窗口");'
browser.execute_script(js)
- 但通常,打开了新的页面后,句柄仍然会留在原页面,所以查找元素等的操作仍然是在原页面进行;
- 这个时候就需要使用句柄来切换网页操作了
- browser.current_window_handle 返回现在当前窗口的句柄
- browser.window_handles 返回当前浏览器所有句柄列表(如果网页是按顺序打开的,则h返回的句柄顺序应该就是网页顺序)
- browser.switch_to_window(handle) 可以跳到指定句柄的网页窗口
- browser.close() 关掉当前网页窗口
- browser.quit() 退出浏览器
常见问题
动态id
如果需要定位的元素具有id属性,但id属性中含有一长串不规律的数字,那很可能就是动态 id了;我们也可以通过刷新网页来验证某id属性是否为动态id;如果遇到了动态id,则选择其他的定位方法即可,例如相邻选择器和后代选择器。
内嵌网页iframe
内嵌网页很好理解,就是在一个网页中嵌入了另外一个网页;而但我们browser获取的是外层网页的信息,就无法定位到内层网页中的元素;内嵌网页都是被一个iframe元素所包围的,所以我们需要先定位到这个iframe元素,接着再指定browser来跳转到iframe元素内的内嵌网页中来查找元素。
具体操作:
element = browser.find_element_by_css_selector("iframe") #第一步:定位iframe元素
browser.switch_to.frame(element) #第二步:跳转到内嵌网页中
# 现在就可以在内嵌网页中定位内嵌网页中的元素了
点击速度过快
大部分网页的数据都是异步加载的,在我们操作网页的过程中,网页也在获取信息来生成其他的元素,如果我们需要定位的元素是异步生成的话,就需要等待数据传输;这个使用多使用一下time.sleep(1)和try-except来等待数秒就ok。