《selenium官方文档》读书笔记
2021-04-24 21:12:20 22 举报
AI智能生成
如果你发现requests不管用了,尝试用selenium,你会回来感谢我的。 当然,selenium还有很多高效的玩法,比如,当因为工作需要在数据平台上传大量数据的时候,使用selenium库可以自动高效地完成任务。
作者其他创作
大纲/内容
元素定位
普通定位方法
根据id
browser.find_element_by_id('idname')
根据class_name
browser.find_elements_by_class_name('dataintable')
根据name属性
browser.find_element_by_name('username')
一般登录表单中会有name且是唯一的,所以通过name会很方便的定位到相应的元素。<br>如上图,百度网盘的用户名和密码输入框的name属性分别为userName,password<br>
根据link
browser.find_elements_by_link_text("编程教程")
根据链接文本定位元素
browser.find_elemrnts_by_partial_text("教程")
上面两个结果是一样的
根据XPATH
browser.find_element_by_xpath()
xpath语法
html
html = etree.HTML('text')
html的层级结构
选取节点
<font color="#fdb813">/</font>
绝对路径
<b><font color="#fdb813">html.xpath("/html/body/div/ul/li")</font></b>
从html文档树的根目录开始,按照层级关系,一层一层解析,直至li标签,如果层级少一个,则没有结果。
绝对路径更多用于定位某个标签的子节点。
html.xpath("//ul/li")
elements = html.xpath("//ul/li")
<b><font color="#fdb813">//</font></b>
相对路径【跳级】
<b>html.xpath("//div//li")</b>
找到div,再从div中所有后代标签中找到li标签
<font color="#fdb813">.</font>
选取当前节点
例子,选取当前li节点下所有的a标签的文本。
如果用 element.xpath("//a/text()"),则会返回所有a标签,而不是当前节点的下,子节点a。
如果没有限定当前节点的情况
<b><font color="#fdb813">..</font></b>
当前节点的父节点
轴
<b><font color="#fdb813">html.xpath("//ul/child::li")</font></b>
ul/child::li
ul节点下所有的li子节点,
ul/parent::*
返回当前节点的父节点
ul/descendant::*
返回ul节点下所有的后代节点
ul/descendant-or-self::*
返回当前节点以及当前节点所有的后代节点
ul/ancestor::*
返回当前节点所有的祖先节点
ul/ancestor-or-self::*
返回当前节点和当前节点所有的祖先节点
ul/following::*
返回当前节点结束后,所有的节点
ul/preceding::*
返回当前节点前的所有节点
ul/preceding-sibling::*
返回当前节点的同级节点
ul/namespace::*
返回当前节点命名空间的节点
xml的命名空间
限定条件
<b><font color="#fdb813">[1]</font></b>
<b><font color="#fdb813">html.xpath("//ul/li[1]")</font></b>
选取ul下第一个li元素
注意第一个元素为1而不是0
<b><font color="#fdb813">[last()]</font></b>
<b><font color="#fdb813">html.xpath("//ul/li[last()]")</font></b>
选取ul下最后一个li元素
<b><font color="#fdb813">[position()=1]</font></b>
html.xpath("//ul/li[postion()=1]")
选取位置为1的元素。
也可以选择:<font color="#fdb813"><b>html.xpath("//ul/li[position()>2]")</b></font>
选取位置大于2的li元素
<b><font color="#fdb813">[@class]</font></b>
<b><font color="#fdb813">html.xpath("//ul/li[@class]")</font></b>
选取有 class属性的li元素
<b><font color="#fdb813">[@class='item1']</font></b>
<b><font color="#fdb813">html.xpath("//ul/li[@class='item1']")</font></b>
选取classs属性为item1的li元素
<font color="#fdb813">*</font>
<b><font color="#fdb813">html.xpath("//div//*")</font></b>
选取div标签下,所有的标签
<b><font color="#fdb813">html.xpath("//div[@*]")</font></b>
选取文档中所有具有属性值的标签
|
html.xpath("//li | //a")
选取所有的li标签和a标签
注意 <b><font color="#fdb813">| </font></b>不支持括号语法
比如:寻找div标签下的li标签和a标签
并不支持 html.xpath("//div(//li | //a)")这样的语法
两种解法
html.xpath(<font color="#fdb813"><b>"//div//li | //div//a"</b></font>)
html.xpath(<b><font color="#fdb813">"//div")[0].xpath(".//li | .//a"</font></b>)
运算符
逻辑运算符
and
<b>xml.xpath("//book/year[<font color="#fdb813">./text()='2003' and ../price/text()>40</font>]/text()")</b>
or
<b>author = xml.xpath("//author<font color="#fdb813">[contains(./text(),'J') or contains(./text(),'K')]</font>")</b>
其他逻辑运算符可参考
常用函数
contains()
几种情况
<b><font color="#fdb813">html.xpath("//div/*[contains(./text(),'a')]")</font></b>
在div所有的子节点中,节点文本中含有字符a的节点。
//div[@class="blog-content-box"]//*[contains(./text(),'函数')]
class为blog-content-box的div下所有后代标签间的文本包含“函数”字符的标签。
<b><font color="#fdb813">html.xpath("//div[contains(@class,'cm_area')]")</font></b>
如图,当class有多个属性值时,使用//div[@class='cm_area ns_area_top ']并不能定位到该标签。
找不到结果。遇到这种有多个class属性,可以使用contains函数。
使用contians的结果。
xml.xpath("//book[<b><font color="#fdb813">contains(/,title)</font></b>]")
不仅支持文本包含,也可以查找子标签中含有title节点的book标签
文本相关
stars-with()
//book/author[<b><font color="#fdb813">starts-with(./text(),'J')</font></b>]
所有author节点文本中以J开始的节点。
string-length() 返回字符串长度
xml.xpath("//book//author[<b><font color="#fdb813">string-length(./text())>20</font></b>]/text()")
查找节点文本长度超过20个的节点。
substring-after 和 substring-before
作用:返回指定字符串前/后的字符串。
substring(text,2,5)
返回字符串第2到第5位字符串。如果没有5,则是从第2到最末尾的字符串。
根据css-selector
browser.find_element_by_css_selector()
css选择器的基本语法
直接通过class/id/tag
<b>.类名</b>
<b>browser.find_elements_by_css_selector("<font color="#fdb813">.wrapper</font>")</b>
选取class属性为wrapper的元素
#id名
<b>browser.find_elements_by_css_selector("<font color="#fdb813">#navfirst</font>")</b>
选取id属性为navfirst的元素。
p 标签名
<b>brower.find_elments_by_css_selector("<font color="#fdb813">table</font>")</b>
选取页面所有的table标签。
选择子元素
>
<b><font color="#fdb813">browser.find_elements_by_css_selecor(".dataintable >tbody>tr")</font></b>
选取两个以上元素
,
browser.find_elements.by_css_selector("<b><font color="#fdb813">#navfirst,#tpn</font></b>")
选取id属性为navfirst 和id属性为tpn的标签
与xpath的|类似。xpath("<b><font color="#fdb813">//*[@id='navfirst'] | //*[@id='tpn']</font></b>")
选取所有后代元素
空格
browser.find_elements_by_css_selector("<b><font color="#fdb813">.dataintable tr</font></b>")
选取class属性为dataintable元素所有后代元素中的tr标签。
有次序的选择后代元素
tr:nth-child(n)
.dataintable tr:nth-child(n)
如果:nth-child(2)前没有限定标签,会返回div和所有div的子标签,<br>分别计算各个标签【包括div】的子标签数量。<br>如果有第二个子标签就返回。<br>如果:nth-child(2)前面限定了标签。则只会返回对应的标签。<br>li:nth-child(2)<br>只返回li标签。
tr:nth-of-type(n)
.box :nth-of-type(2)
注意与nth-child的区别。nth-child(2),会将所有的子标签放入容器,返回第2个子标签。<br>nth-of-type(2) 会将所有子标签按照不同类型放入容器中,返回不同类型标签的第2个。
兄弟的后续节点
+
li+li
紧贴div标签的p标签。如果紧贴是其他标签则不定位。
[]属性选择
[attribute]
选择所有attribute属性的标签
[class]
选择所有有class 属性的标签
li[class]
选择所有有class属性的li标签
<b>div :nth-child(n)[class]</b>
div的子标签中有class属性的标签
[attribute=value]
选择属性值为value的标签
[class=li]
选择class属性为li的所有标签
p[class=li]
选择class属性为li的p标签
[attribute<b><font color="#fdb813">~=</font></b>value]
选择属性值包含value的标签。
[class=li]只能定位到class=li 不能定位到class=li bi的标签。
[class~=li]可以定位到 class="li bi"标签。
注意:~包含是属性值,而不是属性字符串 class~=l 并不能定位到class='li'的标签
[attribute<font color="#fdb813"><b>*=</b></font>str]
属性值字符串中包含str的标签
如上面的问题:[class*=l] 是可以定位到 class="li "的标签的。因为*= 是根据属性值的字符串进行匹配的。li字符串 含有l<br>class="lo"也可以匹配。
[attribute<font color="#fdb813"><b>^=</b></font>str]
类似xpath的starts-with。
如果标签属性字符串开头包含指定str,则返回该标签。
如:如 a[href^=https]
[attribute<font color="#fdb813">$=</font>str]
类似xpath的ends-with
如果标签字符串结尾包含指定str,则返该标签
a[href$=asp]定位结尾有asp的a标签。
使用browser.find_elements_by_css_selector("a[href$=asp]") 的结果。
特殊tag的定位
radio
单选框定位相对来说简单一些,直接定位元素,调用click()即可。
checkbox
checkbox需要注意:<br>如果checkbox之前是选中状态,再次click(),又会变成未选中状态。<br>所有在操作CheckBox前,要将所有的CheckBox的状态变为未选中。<br>然后再进行对应的click操作。
初始化点击
按需点击
完整代码
select
selenium 提供了一个管理select 的类Selct可以方便的操作下拉选择框和下拉多选框。使用前先导入Select类。
导入 :<b><font color="#f68b1f">from selenium.webdriver.surport.ui import Select</font></b>
创建select对象:select = <b><font color="#f68b1f">Select(browser.find_element_by_css_selector("#ss_single"))</font></b>
select对象的常用方法
selet.<b><font color="#f68b1f">selet_by_value</font>(</b>' 小张老师')
根据option的value进行选择
select.<b><font color="#f68b1f">select_by_visible_text</font></b>("小张老师")
根据option的可见文本选择
select.<b><font color="#f68b1f">select_by_index</font></b>(0)
根据option的index来选择。需要注意两点
不支持多选。只支持单个数字输入。
起始位置是0和xpath中起始位置是1不同。
反选:
select.<b><font color="#f68b1f">deselect_all()</font></b>
去除所有选择
deselect_by_value('小张老师')
去除选择。value为‘小张老师’的option
deselect_by_visible_text('小张老师')
去除选择。text为小张老师的选项。
deselect_by_index(1)
去除选择第个option
一个例子
子主题
<b><font color="#f68b1f">from selenium.webdriver.surport.ui import Select</font></b>
webelement对象属性和方法
常用的方法
element.clear()
清除文本
element.send_keys(value)
模拟键盘输入。value为输入值
element.click()
模拟点击
element.submit()
模拟提交表单。如果有input输入框,不需要定位确认按钮,直接submit()即可。
例子模拟登录百度网盘
element.get_attribte(name)
例如:获取页面所有a标签的href属性
element.get_attribute('href')
如果获取a标签的文字可以使用
<b><font color="#f68b1f">element.get_attribute('innerHTML')</font></b>
如果想获取a标签的源码可以使用
<b><font color="#f68b1f">element.get_attribute('outerHTML')</font></b>
element.is_displayed()
元素是否可见
element.text
获取当前元素的innerText值。开始标签到结束标签内的文本内容
element.size
当前元素的大小。
element.tag_name
当前元素的tag名称
控制浏览器
创建浏览器对象
chrome = webdriver.Chrome('chromedriver.exe')
打开网址
chrome.get('http://www.baidu.com')
前进和后退
chrome.back() 后退
chrome.forword() 前进
退出
chrome.quit()
刷新浏览器
chrome.refresh()
获取窗口的title
chrome.title
获取当前url
chrome.current_url
多窗口切换和frame切换
获取窗口句柄
获取所有窗口句柄:all_windows = <b><font color="#f68b1f">browser.window_handles</font></b>
返回一个列表,每个元素是各个窗口的id。
获取当前窗口句柄:current_window = <b><font color="#f68b1f">browser.current_window_handle</font></b>
分别获取每个窗口的title。
获取title后,就可以知道操作具体的窗口。然后可以通过,<b><font color="#f68b1f">browser.switch_to.window(window_handles[0])</font></b> 来切换窗口。
也可以使用,<b><font color="#f68b1f">browser.switch_to.window(current_window)</font></b>
<b><font color="#fdb813">browser.switch_to.frame(fame属性)</font></b>
如果网页中有frame标签,无法直接定位到frame内部的元素
直接定位frame内的元素,并不能定位到。
browser<font color="#fdb813">.<b>switch_to.frame('frame1')</b></font>
思路:先定位到frame,然后switch_to.frame(定位方式)
定位方式
frame属性
使用find_element()
回到主页面:browser.<b><font color="#f68b1f">switch_to.default_content()</font></b>
鼠标和键盘事件
先导入ActionChain
<b><font color="#f68b1f">from selenium.common.action_chain import ActionChains</font></b>
基于浏览器对象,创建ac 实例
<b>browser.get('http://www.baidu.com')</b>
ac = <b><font color="#f68b1f">ActionChains(browser)</font></b>
定位元素
btn = browser.find_element_by_name("button")
定义事件
ac.move_to_element(btn) # 鼠标悬停<br>ac.context_click(btn) # 右键点击<br>……
鼠标事件
ac.move_to_element(btn)
鼠标移动到btn元素上并悬停。
ac.click(btn)
单击
ac.context_click(btn)
右键单击
其他事件,如有需要,可参照
键盘事件
与鼠标事件不用,键盘事件不需要实例化ActionChains实例。直接使用send_keys即可。
如果想组合出ctr+A ctr + C
需要导入:from selenium.webdriver.common.keys import Keys
使用
input = browser.find_element_by_tag_name('a')
a.send_keys(Keys.CONTROL,'a')
使用ctr+a
其他键盘事件参考
执行actionchain
ac.perform()
例子
打开百度--悬停更多--悬停音乐--点击
代码
等待
加载网页需要事件,如果在加载前就执行定位操作,则会抛出找不到元素的异常。<br>所以要设置等待事件,等元素加载完在执行定位操作。
设置等待的方法
time.sleep(3)
隐式等待
browser.implicitly_wait(10)
在10内,等待元素加载,如果在10秒内加载完成,则不会抛出异常。
显式等待
需要导入的模块
from selenium.webdriver.surpport.ui import WebDriverWait
from.selenium.webdrvier.surpport import expected_conditions as EC
from selenium.webdriver.common.by import By
创建WebDriverWait()实例
初始化实例的主要参数
browser
对应浏览器驱动。
timeout:5
设置最长等待时间:如果超出这个时间就会抛出异常。
poll_frequency:0.5
多少秒尝试搜索一次。每个0.5秒扫描文档一次。如果找到就停止。
ignored_exceptions
异常提示
调用until(method,value)方法,或者until_not方法
WebDriverWait(browser,5).until(kw,'未找到')
在5秒时间内,如果找到kkw就返回kkw元素,如果没找到就抛出异常。
找到的情况
子主题
没找到的情况:抛出异常!
until(method,message)的实现原理
在webdrvierwait设定的时间条件中,不断的执行method,
<b><font color="#f68b1f">注意:method参数中一定要有browser,否则会报错!</font></b>
如果在限定的时间条件内,method有返回值就返回这个值
如果没有就抛出异常,提示信息可以用 message 来自定义。
EC方法
expected_conditions封装了网页元素查找、可点击、是否可见等众多方法。具体可参考
EC封装的方法中,有些方法本质上是调用browser.find_element和find_elements方法。
源码
presence_of_all_elements_located
presence_of_element_located(locator)
最终会调用find_element方法。
所以在调用EC方法时,需要传递by参数。
find_element和find_elements方法
find_element(by=By.ID,value='kw')
调用EC封装的方法,本身并不会返回find_element 的结果, 而是绑定了by参数和value参数的函数。
使用时,可以直接调用,传入对应的浏览器对象。
这样做的好处,下次如果还想查找id属性为kw 的元素,就不需要在写find_element函数了,直接调用find_kw(browser) 即可。
以上结合使用,可以方便地使用显示等待。
element = WebDriverWait(browser,4,0.5).<b><font color="#99ffff">until(</font><font color="#f68b1f">EC.presence_of_element_located((By.ID,'kw')) </font></b>, <b><font color="#99ffff">message="kw未找到!"</font></b><font color="#99ffff">)</font>
其他操作可参考
0 条评论
下一页