本文章最初发布在 XJHui’s Blog,未经允许,任何人禁止转载!

注意:最新修改版本已发布在 这里,点击前往查看!

关于笔记

  1. 视频地址:bilibili-白月黑羽教编程(34p)
  2. 课件、笔记:http://www.python3.vip/tut/auto/selenium/01/
  3. 学前技能:
    • python基础
    • python3环境、python解释器
    • 前端基础(html、css)
  4. 学后技能:
    • web自动化
    • python小脚本
    • 爬虫(不推荐)

selenium库

概述

  1. 定义:是一个web的自动化测试工具

  2. 官方文档:Selenium with Python

  3. 功能:python中导入selenium库后通过调用函数实现在浏览器中模拟鼠标点击、移动等操作

  4. 使用范围:

    • 模拟登陆
    • 刷网课

原理图

注意:

  1. 安装:selenium库、浏览器(chrome为例)以及浏览器对应版本的驱动
  2. 使用:想实现 点击 操作,只需要调用selenium库中函数
  3. 兼容性:支持Java,Python等多种语言

安装库

  1. 执行命令:

    1
    pip install selenium -i https://mirror.baidu.com/pypi/simple  # 为了保证安装速度,使用了百度镜像

    运行结果:

  2. 验证安装:

    1
    2
    import selenium  # 导入selenium库
    print(selenium.__version__) # 查看版本号

    运行结果:

浏览器及驱动

  1. 安装浏览器:点这里下载

  2. 安装驱动:

    • 查看chrome版本:

    • 点击 这里 查找对应驱动下载并解压:

      注意:

      • 驱动和浏览器的版本号越接近越好,略有差别(比如72和73)也行
      • 解压路径不要出现中文符号、空格等
      • 解压后为一个.exe文件,不需要安装

简单示例

开启浏览器

  1. 代码:

    1
    2
    3
    from selenium import webdriver  # 从selenium库中导入web自动化常用的函数

    wd = webdriver.Chrome(r'd:\tool\chromedriver.exe') # 实例化一个WebDriver类型的对象,参数浏览器驱动路径

    注意:

    • python默认会将 浏览器驱动路径 中的\转义,在其前面添加 r 表示不转义
    • 通过创建的wd(webdriver对象)来操控浏览器
  2. 运行结果:

跳转网址

  1. 代码:

    1
    wd.get('https://plushine.cn')  # 使用get方法,打开一个新网址
  2. 运行结果:

选择元素

根据id

  1. 语法:

    1
    kw = wd.find_element_by_id('kw')  # 根据id选择元素,返回该元素对应的WebElement对象,下文以wb代指
  2. 案例:在百度搜索页面输入plushine并回车

    • 查看文本框的id值(kw):

      注意:控制台查看网页源码的教程 在这里,感谢:百度经验。

    • 查看提交按钮的id值(su):

    • 编写代码:

      1
      2
      3
      4
      5
      kw = wd.find_element_by_id('kw')  # 根据id选择元素
      kw.send_keys('plushine') # .send_keys():文本框中输入文字

      su = wd.find_element_by_id('su')
      su.click() # .click():点击

      运行结果:

根据class

  1. 语法:

    1
    element = wd.find_elements_by_class_name('plant')  # 返回wb类型的对象

    注意区分:

    • element:返回第一个符合条件的元素的wb对象,找不到抛出异常【NoSuchElementException】
    • elements:返回所有符合条件元素的wb对象列表【适合元素的统一处理】,找不到返回空列表
  2. 案例:选择所有class属性为plant的元素

    • 访问网址,选择元素:

      1
      2
      3
      wd.get('http://cdn1.python3.vip/files/selenium/sample1.html')  # 打开网址

      elements = wd.find_elements_by_class_name('plant') # 查找class等于plant的元素,elements返回列表
    • 查看对象内容(debug):

      1
      # 最后一行添加pass,并断点调试,详见下图

      运行结果:

      注意:如果使用print是无法查看对象内容的:

      1
      print(elements)

      运行结果:

    • 输出元素text属性值:

      1
      2
      for element in elements:
      print(element.text) # .text:查看内部文字(下文会详解)

      运行结果:

根据tag

  1. 代码:

    1
    2
    3
    4
    spanList = wd.find_elements_by_tag_name('span')  # 返回所有标签为span元素的WebElement对象

    for span in spanList:
    print(span.text) # 输出标签内部文字
  2. 运行结果:

根据wb

  1. wb(WebElement):通过find函数选择元素返回值类型为wb

  2. 案例:分别从全局和局部选择span标签,判断返回值是否相同

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    wd.get('http://cdn1.python3.vip/files/selenium/sample1.html')
    wb = wd.find_element_by_id('container') # find返回值类型为wb

    wdElement = wd.find_elements_by_tag_name('span') # webdriver中查找元素
    weElement = wb.find_elements_by_tag_name('span') # webelement中查找元素

    print("-------全局范围wd-----")
    print(len(wdElement))

    print("-------局部范围wb-----")
    print(len(weElement))
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
       
    运行结果:

    <img src="https://cdn.jsdelivr.net/gh/xingjiahui/[email protected]/2020/10/20/5d9843f5f36fc578427ab8ae660cbf95.png" width="70%"/>

    ## 隐式等待

    1. 案例:百度搜索 `plushine` ,获取第一条搜索结果:

    <img src="https://cdn.jsdelivr.net/gh/xingjiahui/[email protected]/2020/10/20/d7ca6f337c1cc11a0b79b56dfae17dfc.png" width="70%"/>

    - 程序代码:

    ```python
    wd.get('https://baidu.com') # 访问百度搜素首页
    wd.find_element_by_id('kw').send_keys('plushine\n') # 通过id选择元素,通过send_keys()填充文本,\n:回车

    element = wd.find_element_by_id('1') # 通过id选择元素
    print(element.text) # 输出返回元素
    • 报错截图:

  3. 原因分析:

    1
    2
    3
    element.send_keys('plushine\n')  # 回车后,开始从百度服务器接收数据

    element = wd.find_element_by_id('1') # 查找id为1的元素,但此时数据还未完全获取导致查找失败
  4. 解决方法(使用隐式等待):

    • 语法:

      1
      2
      wd = webdriver.Chrome(r'd:\tool\chromedriver.exe')  # 创建Chrome浏览器的WebDriver对象
      wd.implicitly_wait(max) # 其中max表示最大等待时间(s)
    • 原理:当元素查找失败时,会每隔0.5s检查一下能否找到元素,直至最大等待时间报错

  5. 案例:百度搜索 plushine ,获取第一条搜索结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from selenium import webdriver

    wd = webdriver.Chrome(r'd:\tool\chromedriver.exe')
    wd.implicitly_wait(10) # 设置最大等待时间为10s

    wd.get('https://baidu.com')

    wd.find_element_by_id('kw').send_keys('plushine\n')

    element = wd.find_element_by_id('1')
    print(element)

    运行结果:

操控元素

常用方式

前面案例中已经多次使用了,这里不再赘述

  1. 点击:.click()【a标签、按钮等均可点击】
  2. 输入字符串:.send_keys()
  3. 获取元素内容:.text

获取标签属性

  1. 语法:

    1
    element.get_attribute('name')  # 注意:element是一个wb对象,get_attribute:获取name属性值
  2. 案例:通过id选择元素并获取该元素的srcid属性值

    • 程序代码:

      1
      2
      3
      element = wd.find_element_by_id('1')

      print(element.get_attribute('srcid'))
    • 运行结果:

获取html

  1. 使用.get_attribute()可以获取某元素的html代码,当参数分别为text、outerHTML、innerHTML时的结果如右图:

  2. 案例:分别输出text、get_attribute(‘outerHTML’)),get_attribute(‘innerHTML’))的结果:

    1
    2
    3
    4
    5
    6
    7
    element = wd.find_element_by_id('h1')  # 查找id为h1的元素
    print("-------text-------")
    print(element.text) # 元素内部文字
    print("-------outerHTML-------")
    print(element.get_attribute('outerHTML')) # 整个元素对应的html
    print("-------innerHTML-------")
    print(element.get_attribute('innerHTML')) # 元素内部html

    运行结果:

    注意:有些内容使用text可能无法获取,可以尝试使用:

    • element.get_attribute('innerText')
    • element.get_attribute('textContent')

获取输入框内容

注意:对于输入(搜索)框,不可以使用id或class来获取里面的内容

  1. 案例:百度搜索框中输入 plushine ,返回刚刚输入的内容

    1
    2
    3
    4
    5
    wd.find_element_by_id('kw').send_keys('plushine')  # 文本框中输入plushine

    element = wd.find_element_by_id('kw') # 通过id选择文本框

    print(element.get_attribute('value')) # 通过get_attribute('value')获取文本框中的内容

    运行结果:

  2. 输入 wd.find_element_by_id('kw').send_keys('plushine') 的类型:

    1
    print(type(wd.find_element_by_id('kw').send_keys('plushine')))

    运行结果:

    因为 element.get_attribute('value') 中要求element的类型是wb对象,所以下面的代码是错误的:

    1
    2
    3
    element = wd.find_element_by_id('kw').send_keys('plushine')  # 此时element的类型为NoneType

    print(element.get_attribute('value'))

CSS选择器

根据标签选择

  1. 案例:选择所有标签为div的元素并输出其内部文字

    1
    2
    3
    4
    5
    6
    wd.get('http://cdn1.python3.vip/files/selenium/sample1.html')

    elements = wd.find_elements_by_css_selector('div')

    for element in elements:
    print(element.text)

    运行结果:

  2. 注意:

    • 其它标签也具有相同的用法,不再列举
    • 也都可以使用 wd.find_element_by_css_selector() 来选择元素

根据属性选择

  1. 案例:选择所有class属性为animal的元素,并输出整个元素内容(class、id)

    1
    2
    3
    4
    elements = wd.find_elements_by_css_selector('.animal')  # class用.表示,id用#表示

    for element in elements:
    print(element.get_attribute('outerHTML'))

    运行结果:

  2. 案例:选择下面代码中的外部元素(其它属性)

    1
    <a href="http://www.miitbeian.gov.cn">苏ICP备88885574号</a>

    注意:href不像class、id可以使用特定的符号表示,但依然可以通过css选择器选择元素

    1
    2
    3
      # 当没有class、id时可以使用[属性=""]来选择元素
    element = wd.find_element_by_css_selector('[href="http://www.miitbeian.gov.cn"]')
    print(element.get_attribute('outerHTML'))

    运行结果:

  3. 技巧:每次都需要运行代码才能判断css选择器是否正确?有没有简便方法?有,Chrome控制台的搜索功能

    • 打开chrome控制台,点击下图位置的 元素

    • 按下快捷键:ctrl+f,出现搜索框:

    • 输入css选择器可筛选出符合条件的元素,大大节省了调试时间:

子元素和后代元素

  1. 代码块:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <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>
    </div>
    • 子元素:layer1、layer2都是container的子元素,同理 inner11是layer1的子元素
    • 后代元素:inner11、inner12、inner21都是container的后代元素,但不是其子代元素
  2. 语法:

    1
    2
    3
    wd.find_element_by_css_selector('#container > #layer1 > #inner11')  # 子代元素之间用 >
    wd.find_element_by_css_selector('#container #inner11') # 后代元素之间用空格
    print(element.get_attribute('outerHTML')) # 打印外部元素

    运行结果:

联合使用

为了便于表示,下面代码中省去了 wd.find_element_by_css_selector()

  1. 标签和属性联用:

    1
    2
    '#container > div'  # id为container的子元素中标签为div的元素(之间有空格或>代表描述的是不同元素)
    'span.copyright' # class为copyright且标签为span的元素(之间无空格或>代表描述的是同一个元素)
  2. 两个选择器联用(逗号分隔,or关系):

    1
    2
    3
    elements = wd.find_elements_by_css_selector('.plant ,.animal')  # 选取class属性为plant或animal的元素
    for element in elements:
    print(element.get_attribute('outerHTML'))

    运行结果:

  3. 案例:获取.vsc-initialized 下 #t1 和 #t2 元素的css选择器

    1
    2
    '.vsc-initialized (#t1 , #t2)'  # 错误,因为括号不能用在css选择器中
    '.vsc-initialized #t1 , .vsc-initialized #t2' # 正确方法(略显笨重,不过后面会将其它简单方法)

    运行结果:

按次序选择子节点

  • 父元素的第n个子节点:

    1
    2
    element = wd.find_element_by_css_selector('span:nth-child(2)')  # 查询第二个span标签
    print(element.get_attribute('outerHTML'))

    运行结果:

    注意:

    • 使用 :nth-last-child(2) 表示选择倒数第二个子元素
    • 使用 span:nth-child(2) (标签属性联用),表示选择第二个且标签为span的子元素
  • 父元素的第几个某类型的子节点:

    1
    2
    element = wd.find_element_by_css_selector('span:nth-of-type(2)')
    print(element.get_attribute('outerHTML'))

    运行结果:

  • 奇数、偶数节点:

    1. 案例:选择#t1的偶数子元素:

      1
      2
      element = wd.find_element_by_css_selector('span:nth-child(even)')
      print(element.get_attribute('outerHTML'))

      运行结果:

    2. 注意:选取偶数子元素只需将 even 更换为 odd 即可

选择弟弟节点

  1. 为什么是“弟弟”节点?

  2. 案例:使用css选择器中弟弟节点选择方法,选择下图中的span标签

    • 代码:

      1
      2
      3
      4
      wd.get("http://cdn1.python3.vip/files/selenium/sample1a.html")

      element = wd.find_element_by_css_selector('#t2>h3+span') # css选择器中使用'+'表示兄弟节点的选择
      print(element.text)
    • 运行结果:

切换frame/窗口

切换frame

  1. frame、iframe的作用:在frame或iframe标签之间存放完整的html代码,实现网页嵌套

    注意:selenium默认不会获取iframe内部元素

  2. 案例:输出iframe内部满足class=”.plant”的元素

    1
    2
    3
    4
    5
    6
    7
    8
    wd.get('http://cdn1.python3.vip/files/selenium/sample2.html')

    wd.switch_to.frame('innerFrame') # 使用switch_to将操作范围切换到iframe内部,参数为iframe的name属性或一个wb对象

    elements = wd.find_elements_by_class_name('plant')

    for element in elements:
    print(element.get_attribute('outerHTML'))

    运行结果:

  3. 案例:执行完案例2后点击iframe外部按钮

    1
    2
    3
    wd.switch_to.default_content()  # 先将操作范围切换到iframe外部

    wd.find_element_by_css_selector('#outerbutton').click()

    运行结果:

切换窗口

使用js或点击超链接打开新标签页后,窗口并不会自动切换,需要手动操作

  1. 区分标签页和窗口:

  2. 语法:

    1
    wd.switch_to.window(handle)  # 使用switch_to.window()将窗口切换为目标窗口,参数为目标窗口的handle值

    注意:目标窗口的handle值是未知的,但window_handles中存放了该网页的所有handle值,可依次尝试

  3. 案例:点击超链接访问必应首页,文本框中输入 “plushine”

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    wd.get('http://cdn1.python3.vip/files/selenium/sample3.html')

    wd.find_element_by_css_selector('a[href="http://www.bing.com"]').click()

    for handle in wd.window_handles: # 遍历所有handle,依次切换,直至满足条件(handle对应的title与目标窗口一致)
    wd.switch_to.window(handle)
    if '必应' in wd.title:
    break

    wd.find_element_by_css_selector('input.b_searchbox').send_keys('plushine')

    运行结果:

  4. 案例:将操作范围切换回原来的标签,并点击按钮

    • 方式一:for循环寻找正确的handle

    • 方式二:记录最开始打开的标签handle值,然后直接跳转

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      wd.find_element_by_css_selector('a[href="http://www.bing.com"]').click()

      mainHandle = wd.current_window_handle # 记录当前窗口handle值

      for handle in wd.window_handles:
      wd.switch_to.window(handle)
      if '必应' in wd.title:
      break

      wd.find_element_by_css_selector('input.b_searchbox').send_keys('plushine')

      wd.switch_to.window(mainHandle) # 跳转到最开始打开的标签

      wd.find_element_by_css_selector('#outerbutton').click()

      运行结果:

选择框

radio

  1. 介绍:radio是单选框,最多只能选择一项

  2. 案例:先打印当前选中的老师,再选中小雷老师

    1
    2
    3
    4
    5
    6
    7
    wd.get('http://cdn1.python3.vip/files/selenium/test2.html')

    element = wd.find_element_by_css_selector('input[type="radio"][checked="checked"]')

    print(element.get_attribute('value'))

    wd.find_element_by_css_selector('input[type="radio"][value="小雷老师"]').click()

    运行结果:

    注意:使用 element.text 是获取不到其内部文字的,因为input是单标签

checkbox

  1. 介绍:checkbox是复选框,可选择多项

  2. 案例:只选中小雷老师

    1
    2
    3
    4
    5
    6
    7
    8
    wd.get('http://cdn1.python3.vip/files/selenium/test2.html')

    elements = wd.find_elements_by_css_selector('input[type="checkbox"][checked="checked"]')

    for element in elements:
    element.click()

    wd.find_element_by_css_selector('input[type="checkbox"][value="小雷老师"]').click()

    运行结果:

select

  1. 定义:select是下拉框,每个option标签是一个选项,有单选下拉框也有多选下拉框

  2. select类:selenium中一个专门操作select下拉框的类

  3. 案例:单选下拉框中使用select类选择小雷老师

    1
    2
    3
    4
    5
    6
    7
    8
    from selenium.webdriver.support.ui import Select  # 导入Select类

    wd.get('http://cdn1.python3.vip/files/selenium/test2.html')
    select = Select(wd.find_element_by_css_selector('#ss_single')) # 创建select类时的参数为wb对象

    select.select_by_index(1) # 根据序号选择(从0开始),还有下面两种选择方法(结果相同)
    # select.select_by_value('小雷老师') # 根据option对应的属性选择
    # select.select_by_visible_text('小雷老师') # 根据网页可见文字选择

    运行结果:

  4. 案例:多选下拉框中使用selenium的select类选择小江老师和小凯老师

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from selenium.webdriver.support.ui import Select  # 导入Select类

    wd.get('http://cdn1.python3.vip/files/selenium/test2.html')
    select = Select(wd.find_element_by_css_selector('#ss_multi')) # 创建select类时的参数为WebElement对象

    select.deselect_all() # 取消全部选择

    select.select_by_index(0) # 使用下标选取(从0开始)
    select.select_by_index(2)

    运行结果:

    注意:select_by_value()select_by_visible_text() 的方法依旧适用于多选框

弹出框

alert

  1. 定义:alert弹框,可以显示一段text文本和一个accept(确定)按钮

  2. 案例:获取alert弹出框显示的text内容后点击accept(确定)按钮

    1
    2
    3
    4
    5
    6
    wd.get('http://cdn1.python3.vip/files/selenium/test4.html')

    wd.find_element_by_css_selector('#b1').click() # 点击页面的按钮后显示alert弹窗

    print(wd.switch_to.alert.text) # 获取alert弹出框显示的text内容
    wd.switch_to.alert.accept() # 点击accept按钮

    运行结果:

confirm

  1. 定义:confirm弹框,可以显示一段text文本、一个accept(确定)按钮和一个dismiss(取消)按钮

  2. 案例:获取confirm弹出框显示的text内容后点击dismiss(取消)按钮

    1
    2
    3
    4
    5
    6
    wd.get('http://cdn1.python3.vip/files/selenium/test4.html')

    wd.find_element_by_css_selector('#b2').click() # 点击页面的按钮后显示confirm弹窗

    print(wd.switch_to.alert.text) # 获取confirm弹出框显示的text内容
    wd.switch_to.alert.dismiss() # 点击dismiss按钮

    运行结果:

    注意:switch_to.alert.accept() 函数依然适用于confirm 弹出框

prompt

  1. 定义:prompt弹框,可以显示一个input文本框、一段text文本、一个accept(确定)按钮和一个dismiss(取消)按钮

  2. 案例:文本框中输入 plushine.cn 后点击确定

    1
    2
    3
    4
    5
    6
    7
    wd.get('http://cdn1.python3.vip/files/selenium/test4.html')

    wd.find_element_by_css_selector('#b3').click() # 点击页面的按钮后显示prompt弹窗

    print(wd.switch_to.alert.text) # 获取prompt弹出框显示的text内容
    wd.switch_to.alert.send_keys('plushine.cn') # 向文本框中输入文本
    wd.switch_to.alert.accept() # 点击accept按钮

    运行结果:

更多操控方法

鼠标悬停

  1. 引入:在 魅族官网 选择产品时需要将鼠标悬停在导航栏上,才能看到内部元素

  2. ActionChains类:实现右键点击、双击、移动到某个元素、拖拽等鼠标操作

  3. 案例:将鼠标【移动并悬停】在导航栏中 配件 位置上

    1
    2
    3
    4
    5
    6
    7
    8
    from selenium.webdriver.common.action_chains import ActionChains  # 导入ActionChains类

    wd.get('https://www.meizu.com/')
    ac = ActionChains(wd) # 创建ActionChains对象,参数为wd对象

    ac.move_to_element(
    wd.find_element_by_css_selector('#meizu-header-link > :nth-child(3)')
    ).perform()

    运行结果:

    注意:更多ActionChains类的使用方法请自行查找

冻结界面

  1. 问题:通过控制台无法展开商品

  2. 解决:先冻结界面,再通过控制台选择

    • 控制台输入如下JavaScript代码:

      1
      setTimeout(function(){debugger}, 5000)  # 设置定时器,5秒后冻结界面

      运行结果:

    • 快速将鼠标悬停在网站导航栏中使商品展示:

    • 等待窗口冻结:

    • 选择商品元素:

执行js

  1. 语法:

    1
    2
    3
    4
    js = """
    console.log("{}");
    """.format('hello world!')
    wd.execute_script(js) # 执行上面的js代码

    注意:

    • js代码可以使用放在三个双引号之间(如上面格式)
    • js中注释符号为//,注意和python注释的符号区分
  2. 案例:使用js打开一个新的标签页,并将窗口切换到该标签,关闭新标签页并将窗口切换回最开始的标签页

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    from selenium import webdriver

    wd = webdriver.Chrome('D:\environment\chromedriver.exe')

    wd.get("https://plushine.cn")
    print(wd.title) # 通过打印窗口title,判断所在的标签页

    js = """ //js代码
    window.open('https://www.baidu.com')
    """
    wd.execute_script(js) # 运行js代码

    hanldeList = wd.window_handles
    wd.switch_to.window(hanldeList[-1]) # 打开最新的标签页
    print(wd.title) # 打印title,判断窗口是否切换成功

    wd.close() # 关闭当前标签页
    wd.switch_to.window(hanldeList[0]) # 将窗口切换切换到最开始的标签页

    print(wd.title)

    运行过程:

    运行结果:

    注意:常用的窗口切换

    • handles = wd.window_handles #获取当前浏览器的所有窗口句柄

    • wd.switch_to.window(handles[-1]) #切换到最新打开的窗口

    • wd.switch_to.window(handles[-2]) #切换到倒数第二个打开的窗口

    • wd.switch_to.window(handles[0]) #切换到最开始打开的窗口

Xpath

我一般都是用css选择器,当css不能选择时再使用xpath,所以总结的不全面

  1. 定义:堂兄节点,下图橙色框中两个节点互为堂兄节点

  2. 语法:

    • 选择子节点:/
    • 选择父节点:/..
    • 选择div标签:div
    • 选择第二个子元素且标签为div的节点:div[2]
  3. 案例:使用css选择器选择上图中的span标签,再使用xpath选择div标签

    1
    2
    3
    4
    element = wd.find_element_by_css_selector('interaction-status evaluation')  # 先使用css选择器,选择span标签
    str = element.find_element_by_xpath('./../div[2]') # 再使用xpath语句选择div

    print(str.text)
  4. 注意:

    • wb的基础上选择要在xpath语句最前面加上’.’(类似css的局部选择时)
    • wd的基础上选择不需要添加

写在后面

  1. 课程知识很全,老师讲解很细
  2. b站还有老师的app自动化和Python Qt的课程,有时间就看
  3. 明天开始写云班课互评作业的脚本,有可能就写刷课的脚本,代码到时候会开源

不足之处,欢迎留言,会及时回复,及时更正!

创作不易,感谢支持!