python + selenium 操作浏览器 常用操作、常见问题及解决 [ 元素定位 CSS选择器 无法定位元素 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。

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值