首先,先将一个测试html保存到本地,后续案例就按照这个页面来演示啦!

代码如下:

<!DOCTYPE html>
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        <title>不予の测试笔记</title>

        <style>
            .animal {color: red;}
        </style>
    <style class="mpa-style-fix ImageGatherer">.FotorFrame{position:fixed!important}</style><style class="mpa-style-fix SideFunctionPanel">.weui-desktop-online-faq__wrp{top:304px!important;bottom:unset!important}.weui-desktop-online-faq__wrp .weui-desktop-online-faq__switch{width:38px!important}</style></head>

    <body>
        <a>用户名:</a>
        <input id="username" class="username">
        <a>密码</a>
        <input id="password" name="password">

        <div class="plant"><span>土豆</span></div>
        <div class="plant"><span>洋葱</span></div>
        <div class="plant"><span>白菜</span></div>

        <div class="animal"><span>狮子</span></div>
        <div class="animal"><span>老虎</span></div>
        <div class="animal"><span>山羊</span></div>
        <p>测试啦</p>
        <p>再一次测试啦</p>
        <input type="text" id="searchtext">

        <div id="container">

            <div id="layer1">
                <div id="inner11">
                    <span>内层11</span>
                </div>
                <div id="inner12">
                    <span>内层12</span>
                </div>
            </div>

            <div id="layer2">
                <div id="inner21">
                    <span>内层21</span>
                </div>
            </div>
            <a href="https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1" target="_blank"
               class="mnav sp dot">新年不快乐啊</a>
            <a href="https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1" target="_blank"
               class="mnav sp dot">新年快乐啊</a>
            <a href="https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1" target="_blank"
               class="mnav sp dot">新年快乐啊</a>
            <ul>
        <li class="li">111</li>
        <li class="li">222</li>
        <li class="li">333</li>
        </ul>

        </div>
    </body>
</html>

辣么,我们接下来就说下有哪些元素定位的方式呢

方式一:通过元素的id

# 找到id = username的元素
username = driver.find_element('id', "username")
# 输入值 师不予
username.send_keys("师不予")
# 找到od = password的元素
password = driver.find_element('id', "password")
# 输入值 1234
password.send_keys("1234")

知识点

在前端,一般一个id值是唯一的,只属于一个元素

方式二:通过元素的class

# 根据 class name 选择元素,返回的是 一个列表
# 里面 都是class 属性值为 animal的元素对应的 WebElement对象
element = driver.find_element(By.CLASS_NAME, "animal")
print(element.text)

# 输出
狮子

知识点

  • 在前端,一般多个元素共用一个class
  • 但 find_element 只返回第一个匹配到class的元素
  • 坏处:当找不到元素则报错
  • 如果想返回所有匹配到class的元素,可看下面代码
elements = driver.find_elements(By.CLASS_NAME, "animal")
# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容
for element in elements:
    print(element.text)

driver.quit()

执行结果

狮子
老虎
山羊

知识点

  • 返回的是一个元素列表,若只匹配到一个也是列表
  • 好处:当没有找到元素时不会报错,而是返回空列表 []

方式三:通过元素的name

# =====通过 元素name查找元素(仅返回匹配到的第一个)
password = driver.find_element_by_name("password")

# =====输入值 123
password.send_keys("123")

知识点

  • 和class一样,也有可能有多个元素共用一个name
  • 但 find_element 只返回第一个匹配到name的元素
  • 想返回多个的话,和class一样,需要调用 find_elements 方法,这里不再赘述,写法和上面一致

方式四:通过元素标签

根据 tag 名 选择元素

类似的,我们可以通过指定 参数为 By.TAG_NAME ,选择所有的tag名为 p的元素,如下所示

# 根据 tag name 选择元素,返回的是 一个列表
# 里面 都是 tag 名为 p 的元素对应的 WebElement对象
elements = driver.find_elements(By.TAG_NAME, 'p')

# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容
for element in elements:
    print(element.text)

执行结果

测试啦
再一次测试啦

方式五:通过超链接文本

# =====通过 超链接的文本查找元素(仅支持精确匹配)
atext = driver.find_element(By.LINK_TEXT, "新年快乐啊")
print(atext.text)

print("===")
ass = driver.find_elements(By.LINK_TEXT, "新年快乐啊")
for i in ass:
    print(i.text)
driver.quit()

执行结果

新年快乐啊
===
新年快乐啊
新年快乐啊

知识点

  • driver.find_element(By.LINK_TEXT, “新年快乐啊”)是精确匹配,需要文本完全相同才能匹配
  • 若需要返回全部匹配到的元素,也需要用 find_elements(By.LINK_TEXT, “新年快乐啊”)

方式六:通过超链接文本(模糊匹配)

# =====通过 超链接的文本查找元素(支持模糊匹配)
atext = driver.find_element(By.PARTIAL_LINK_TEXT, "快乐")
print(atext.text)

print("===")
ass = driver.find_elements(By.PARTIAL_LINK_TEXT, "快乐")
for i in ass:
    print(i.text)
driver.quit()

执行结果

新年不快乐啊
===
新年不快乐啊
新年快乐啊
新年快乐啊

知识点

  • find_element(By.PARTIAL_LINK_TEXT, “快乐”)支持模糊匹配,包含文本则匹配成功
  • 若需要返回全部匹配到的元素,也需要用driver.find_elements(By.PARTIAL_LINK_TEXT, “快乐”)

方式七:通过xpath(万能,重点)

# ====通过 xpath
lis = driver.find_element(By.XPATH, "//*[@id='container']/ul[1]/li[2]")
print(lis.text)

执行结果

222

注意: xpath 包含的知识点很多,暂时不在这篇幅展开讲,后续会单独补充详细博文哦!

方式八:通过css选择器(万能,重点)

# ====通过css选择器
lis = driver.find_element(By.CSS_SELECTOR, "body > div > ul > li:nth-child(2)")
print(lis.text)

执行结果

222

注意: css选择器 包含的知识点很多,暂时不在这篇幅展开讲,后续会单独补充详细博文哦!

定位方法的总结

定位方法 定位方法1 定位方法2
by_id find_element(“id”,“”) find_element(By.ID,value=’’)
by_xpath find_element(“xpath”,“”) find_element(By.XPATH,value=" ")
by_link_text find_element(“link text”,“”) find_element(By.LINK_TEXT,value=" ")
by_partial_text find_element(“partial link text”,“”) find_element(By.PARTIAL_LINK_TEXT,value=" ")
by_name find_element(“name”,“”) find_element(By.NAME,value=" ")
by_tag_name find_element(“tag name”,“”) find_element(By.TAG_NAME,value=" ")
by_class_name find_element(“class name”,“”) find_element(By.CLASS_NAME,value=" ")
by_css_selector find_element(“css selector”,“”) find_element(By.CSS_SELECTOR,value=" ")

补充—窗口冻结

有些网站上面的元素, 我们鼠标放在上面,会动态弹出一些内容。

比如,百度首页的右上角,有个设置选项
如果我们把鼠标放在上边,就会弹出 下面的各种设置项
如果我们要用 selenium 自动化 点击 搜索设置,就需要 F12 查看这个元素的特征。

但是 当我们的鼠标 从 搜索设置 移开, 这个 栏目就整个消失了, 就没法 查看 其对应的 HTML。
可以使用谷歌开发者工具栏 console里面执行js代码
意思是:过5秒后,执行debugger命令

setTimeout(function(){debugger},5000)

补充:相对定位器

selenium4新增了相对定位策略
当为所需元素构建定位器并不容易时,这些定位器很有用,但很容易在空间上描述元素相对于具有易于构建定位器的元素的位置。
Selenium 使用 JavaScript 函数 getBoundingClientRect() 来确定页面上元素的大小和位置,并且可以使用此信息来定位相邻元素。
找到相关元素。

Selenium 的官网示例

image
它提供的相对定位器有如下:

  • above - 上面
  • below - 下面
  • toLeftOf - 左边
  • toRightOf - 右边
  • near - 附近

above - 上面

如果电子邮件文本字段元素由于某种原因不容易识别,但密码文本字段元素是,我们可以使用它是密码元素“上方”的“输入”元素这一事实来定位文本字段元素。

email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
ele = driver.find_element(email_locator)

below - 下面

如果密码文本字段元素由于某种原因不容易识别,但电子邮件文本字段元素是,我们可以使用它是电子邮件元素“下方”的“输入”元素这一事实来定位文本字段元素。

password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})

toLeftOf - 左边

如果由于某种原因取消按钮不容易识别,但提交按钮元素是,我们可以使用它是提交元素“左侧”的“按钮”元素这一事实来定位取消按钮元素。

cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})

toRightOf - 右边

如果提交按钮由于某种原因不容易识别,但取消按钮元素是,我们可以使用它是取消元素“右侧”的“按钮”元素这一事实来定位提交按钮元素。

submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})

near - 附近

如果相对定位不明显,或者根据窗口大小而变化,可以使用 near 方法来识别最多50px远离提供的定位器的元素。一个很好的用例是使用一个表单元素,该元素没有易于构建的定位器,但其关联的输入标签元素有。

email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})