《最新出炉》系列入门篇-Python+Playwright自动化测试-52- 字符串操作 - 下篇

python,playwright · 浏览次数 : 0

小编点评

本文介绍了在自动化测试中进行字符串操作的方法,包括正则表达式和字符串切片函数split()。文章首先介绍了字符串操作的重要性,然后通过一个测试场景展示了如何使用正则表达式提取关键字,并通过实际代码示例展示了如何应用这些方法。 1. **简介**: - 自动化测试中字符串操作的必要性 - 常见的字符串操作场景 - 正则表达式和字符串切片函数的特点 2. **测试场景**: - 设计测试用例的思考过程 - 使用正则表达式和字符串切片函数的实际应用 - 搜狗和必应搜索结果的对比 3. **字符串正则操作**: - 正则表达式的概念和作用 - re模块的介绍和使用 - 常见的正则表达式符号及其意义 - re模块的常用方法 - 贪婪匹配和非贪婪匹配的区别 4. **项目实战**: - 测试用例的具体实现 - 代码设计的思路 - 实际代码的运行结果和解释 总的来说,文章通过理论介绍和实践代码演示,为读者提供了一套完整的字符串操作解决方案,旨在帮助读者更好地理解和应用这些技巧。

正文

1.简介

在日常的自动化测试工作中进行断言的时候,我们可能经常遇到的场景。从一个字符串中找出一组数字或者其中的某些关键字,而不是将这一串字符串作为结果进行断言。这个时候就需要我们对字符串进行操作,宏哥这里介绍两种方法:正则和字符串切片函数split()。

2.测试场景

宏哥在这里说一下,自己的胡诌的测试场景哈,仅供学习和参考。然后按照宏哥说的进行自动化测试,测试场景:在度娘或者其他搜索引擎中搜索“北京宏哥”,然后搜索完毕,会返回搜索结果,告诉你搜索到多少个“北京宏哥”。宏哥这里分别用搜狗和必应搜索,然后对比她俩谁所搜到的“北京宏哥”多,然后通过对比说明谁的搜索能力强大(搜索结果多说明搜索能力强大)。

3.字符串正则操作

关于这个字符串通过正则提取关键字,正则的这个概念宏哥就在这里赘述一下或许不是很全面,,有兴趣的可以自己查一下。但是宏哥上边说的测试场景就需要用到这一操作(re.sub)。

3.1正则表达式

什么是正则表达式?

  正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。

正则表达式可以干什么?

  • 快速高效的查找与分析字符串
  • 进行有规律查找比对字符串,也叫:模式匹配
  • 具有查找、比对、匹配、替换、插入、添加、删除等能力。

  字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如我们编写爬虫收集数据,首先都得到网页源码,但是我们要如何提取有效数据呢,这时候我们就需要使用正则表达式来进行匹配了。

3.2re模块

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。re 模块使 Python 语言拥有全部的正则表达式功能。

由于Python的字符串本身也用\转义,所以要特别注意:

s = 'ABC\\-001' # Python的字符串
# 对应的正则表达式字符串变成:
# 'ABC\-001'

因此建议使用Python的r前缀,就不用考虑转义的问题了:

s = r'ABC\-001' # Python的字符串
# 对应的正则表达式字符串不变:
# 'ABC\-001'

3.3re模块符号大全

正则表达式模式

模式字符串使用特殊的语法来表示一个正则表达式:

字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

多数字母和数字前加一个反斜杠时会拥有不同的含义。

标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

反斜杠本身需要使用反斜杠转义。

由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于 \\t )匹配相应的特殊字符。

下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

模式描述
^ 匹配字符串的开头
$ 匹配字符串的末尾。
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...] 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re* 匹配0个或多个的表达式。
re+ 匹配1个或多个的表达式。
re? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n} 匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。
re{ n,} 精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。
re{ n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a|b 匹配a或b
(re) 匹配括号内的表达式,也表示一个组
(?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re) 类似 (...), 但是不表示一个组
(?imx: re) 在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#...) 注释.
(?= re) 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re) 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。
(?> re) 匹配的独立模式,省去回溯。
\w 匹配数字字母下划线
\W 匹配非数字字母下划线
\s 匹配任意空白字符,等价于 [\t\n\r\f]。
\S 匹配任意非空字符
\d 匹配任意数字,等价于 [0-9]。
\D 匹配任意非数字
\A 匹配字符串开始
\Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z 匹配字符串结束
\G 匹配最后匹配完成的位置。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等。 匹配一个换行符。匹配一个制表符, 等
\1...\9 匹配第n个分组的内容。
\10 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

注意:表中re指的是表达式而不是字面的re这两个字母

正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

正则表达式对象

re.RegexObject

re.compile() 返回 RegexObject 对象。

re.MatchObject

group() 返回被 RE 匹配的字符串。

    • start() 返回匹配开始的位置
    • end() 返回匹配结束的位置
    • span() 返回一个元组包含匹配 (开始,结束) 的位置

3.4re模常用方法

3.4.1re.match()

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

函数语法

re.match(pattern, string, flags=0)

函数参数说明:

参数描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见上方可选标志表格

匹配成功re.match方法返回一个匹配的对象,否则返回None。

实例及输出:

第一个匹配成功,第二个则失败

3.4.2re.search()

re.search 扫描整个字符串并返回第一个成功的匹配。

函数语法:

re.search(pattern, string, flags=0)

函数参数说明:

参数描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见上方可选标志表格

匹配成功re.search方法返回一个匹配的对象,否则返回None。

实例及输出:

3.4.3compile 函数

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,re函数使用。

提前编译可减少多次正则匹配的运行时间

语法格式为:

re.compile(pattern[, flags])

参数:

  • pattern : 一个字符串形式的正则表达式
  • flags 可选,表示匹配模式
3.4.4re.findall()

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

注意: match 和 search 是匹配一次 findall 匹配所有。

用法1

直接使用的语法格式为:

re.findall(pattern, string, flags)

参数:

  • pattern 正则表达式
  • string 待匹配的字符串
  • flags re的一些flag,可不写

实例及输出:

用法2

compile后使用findall的语法格式为:

re.findall(string, pos, endpos)

参数:

  • string 待匹配的字符串。
  • pos 可选参数,指定字符串的起始位置,默认为 0。
  • endpos 可选参数,指定字符串的结束位置,默认为字符串的长度。

实例及输出:

3.4.5re.finditer

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

re.finditer(pattern, string, flags=0)

实例及输出:

3.4.6re.split

split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

re.split(pattern, string[, maxsplit=0, flags=0])

参数:

参数描述
pattern 匹配的正则表达式
string 要匹配的字符串。
maxsplit 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见上方可选标志表格

实例:

用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码:

>>> 'a b   c'.split(' ')
['a', 'b', '', '', 'c']

发现无法识别连续的空格,用正则表达式试试:

>>> re.split(r'\s+', 'a b   c')
['a', 'b', 'c']

无论多少个空格都可以正常分割。加入,试试:

>>> re.split(r'[\s\,]+', 'a,b, c  d')
['a', 'b', 'c', 'd']

再加入;试试:

>>> re.split(r'[\s\,\;]+', 'a,b;; c  d')
['a', 'b', 'c', 'd']
3.4.7groups()

我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

匹配对象方法描述
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

实例及输出:

3.4.8re.sub

Python 的re模块提供了re.sub用于替换字符串中的匹配项。

语法:

re.sub(pattern, repl, string, count=0, flags=0)

参数:

  • pattern : 正则中的模式字符串。
  • repl : 替换的字符串,也可为一个函数。
  • string : 要被查找替换的原始字符串。
  • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
  • flags : 编译时用的匹配模式,数字形式。

前三个为必选参数,后两个为可选参数。

实例及输出:

repl 参数可以是一个函数

以下实例中将字符串中的匹配的数字乘于 2:

实例及输出:

3.5贪婪匹配

需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。举例如下,匹配出数字后面的0

>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')

由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。

必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:

>>> re.match(r'^(\d+?)(0*)$', '102300').groups()
('1023', '00')

3.6正则表达式实例

3.6.1字符匹配
实例描述
python 匹配 "python".
3.6.2字符类
实例描述
[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"
[aeiou] 匹配中括号内的任意一个字母
[0-9] 匹配任何数字。类似于 [0123456789]
[a-z] 匹配任何小写字母
[A-Z] 匹配任何大写字母
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母以外的所有字符
[^0-9] 匹配除了数字外的字符
3.6.3特殊字符类
实例描述
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。

 

4.项目实战

4.1测试用例

首先宏哥根据测试场景进行测试用例的设计,如下:

1.分别在搜狗和必应搜索框“北京宏哥”

2.分别点击查询,观察查询结果

3.分别将查询结果取到

4.提取结果中的数字,保存在变量中

5.对比两个数字的大小

4.2代码设计

4.3参考代码

# coding=utf-8🔥

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2024-04-10
@author: 北京-宏哥
公众号:北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货)
Project: 《最新出炉》系列入门篇-Python+Playwright自动化测试-52- 字符串操作 - 下篇
'''
# 3.导入模块
import re
from playwright.sync_api import Playwright, sync_playwright, expect
def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://www.sogou.com")
    page.locator("#query").fill("北京宏哥")
    page.locator("#stb").click()
    page.wait_for_timeout(1000)
    # 定位 搜狗为您找到相关结果约xxxx个 这个元素
    result = page.locator("//*[@id='main']/div[1]/p")
    # 获取该字段值  "搜索工具 搜狗为您找到相关结果约xxxxx个"
    result_string = result.inner_text()
    print(result_string)
    regEx = "[^0-9]"
    search_number = re.sub(regEx,"", result_string)
    print(search_number)

    page.goto("https://cn.bing.com")
    page.locator("#sb_form_q").fill("北京宏哥")
    page.locator("#search_icon").click()
    page.wait_for_timeout(1000)
    # 定位 必应为xxxx条结果 这个元素
    result1 = page.locator("//*[@id='b_tween_searchResults']/span")
    # 获取该字段值  "约 xxx 个结果"
    result_string1 = result1.inner_text()
    print(result_string1)
    st2 = re.sub(regEx, "",result_string1)
    print(st2)
    # 首先将两个数都转换为int 数据
    a_N = int(search_number)
    b_N = int(st2)
    # 搜狗和必应的搜索结果对比
    if (a_N > b_N):
        print("搜狗牛逼,搜狗威武!!!")
    else:
        print("必应牛逼,必应威武!!!");
    page.wait_for_timeout(20000)
    page.close()
    context.close()
    browser.close()
with sync_playwright() as playwright:
    run(playwright)

4.4运行代码

1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的浏览器的动作。如下图所示:

5.小结

好了,关于字符串的操作,宏哥就介绍到这里,其实两种方法各有千秋,如果其中一种不太合适或者不好用,不妨换另一种方法试一下,没准就成功了。不要钻牛角尖,一条道走到黑哈。还有就是正则表达式的语法,自己去查一下,看一下,半个小时就可以掌握的差不多了,然后要注意实践啊,不然吃一顿饭就忘记了。

与《最新出炉》系列入门篇-Python+Playwright自动化测试-52- 字符串操作 - 下篇相似的内容:

《最新出炉》系列入门篇-Python+Playwright自动化测试-52- 字符串操作 - 下篇

1.简介 在日常的自动化测试工作中进行断言的时候,我们可能经常遇到的场景。从一个字符串中找出一组数字或者其中的某些关键字,而不是将这一串字符串作为结果进行断言。这个时候就需要我们对字符串进行操作,宏哥这里介绍两种方法:正则和字符串切片函数split()。 2.测试场景 宏哥在这里说一下,自己的胡诌的

《最新出炉》系列入门篇-Python+Playwright自动化测试-51- 字符串操作 - 上篇

1.简介 在日常的自动化测试工作中进行断言的时候,我们可能经常遇到的场景。从一个字符串中找出一组数字或者其中的某些关键字,而不是将这一串字符串作为结果进行断言。这个时候就需要我们对字符串进行操作,宏哥这里介绍两种方法:正则和字符串切片函数split()。 2.测试场景 宏哥在这里说一下,自己的胡诌的

《最新出炉》系列入门篇-Python+Playwright自动化测试-50-滚动条操作

1.简介 有些页面的内容不是打开页面时直接加载的,需要我们滚动页面,直到页面的位置显示在屏幕上时,才会去请求服务器,加载相关的内容,这就是我们常说的懒加载。还有就是在日常工作和学习中,经常会遇到我们的页面内容较多,一个屏幕范围无法完整展示内容,我们就需要滚动滚动条去到我们想要的地方,所以有时候我们就

《最新出炉》系列入门篇-Python+Playwright自动化测试-49-Route类拦截修改请求-下篇

1.简介 在日常工作和学习中,自动化测试的时候:在加载页面时,可能页面出现很多不是很重要或者不是我们所关注的,这个时候我们就可以选择不加载这些内容,以提高页面加载速度,节省资源。例如:可能页面上图片比较多,而我们又不关心图片内容。那么,在加载页面时,可以选择不加载图片,以提高页面加载速度。这里我们主

《最新出炉》系列入门篇-Python+Playwright自动化测试-48-Route类拦截修改请求-上篇

1.简介 在日常工作和学习中,自动化测试的时候:在加载页面时,可能页面出现很多不是很重要或者不是我们所关注的,这个时候我们就可以选择不加载这些内容,以提高页面加载速度,节省资源。例如:可能页面上图片比较多,而我们又不关心图片内容。那么,在加载页面时,可以选择不加载图片,以提高页面加载速度。这里我们主

《最新出炉》系列入门篇-Python+Playwright自动化测试-47-自动滚动到元素出现的位置

1.简介 在我们日常工作中或者生活中,经常会遇到我们的页面内容较多,一个屏幕范围无法完整展示内容,我们就需要滚动滚动条去到我们想要的地方,如下图页面,我们虽然在豆瓣首页,但是内容并不完整,如果我们想要直接点击电影模块中的选电影按钮,是需要往下滑动的。当页面超过屏幕的高度时候,需要滚动到元素出现的位置

《最新出炉》系列入门篇-Python+Playwright自动化测试-46-鼠标滚轮操作

1.简介 有些网站为了节省流量和资源,提高加载效率,采用的是动态加载(懒加载)的,也就是当拖动页面右侧滚动条后会自动加载网页下面的内容,不拖动就不会加载的或者通过鼠标滚轮操作。 2.wheel模拟鼠标滚动 wheel模拟鼠标滚动,就是通过调度一个wheel事件。(滚轮事件如果不处理可能会导致滚动,该

《最新出炉》系列入门篇-Python+Playwright自动化测试-45-鼠标操作-下篇

1.简介 鼠标为我们使用电脑提供了很多方便,我们看到的东西就可以将鼠标移动过去进行点击就可以打开或者访问内容,当页面内容过长时,我们也可以使用鼠标滚轮来实现对整个页面内容的查看,其实playwright也有鼠标操作的方法。上一篇文章中已经讲解过鼠标的部分操作了,今天宏哥在这里将剩下的其他操作进行一个

《最新出炉》系列入门篇-Python+Playwright自动化测试-44-鼠标操作-上篇

1.简介 前边文章中已经讲解过鼠标的拖拽操作,今天宏哥在这里对其的其他操作进行一个详细地介绍和讲解,然后对其中的一些比较常见的、重要的操作单独拿出来进行详细的介绍和讲解。 2.鼠标操作语法 鼠标操作介绍官方API的文档地址:https://playwright.dev/docs/api/class-

《最新出炉》系列入门篇-Python+Playwright自动化测试-43-分页测试

1.简介 分页测试,这种一般都是公共的方法系统中都写好了,这种一般出现是数据展示比较多的时候,会采取分页的方法,而且比较固定,一般是没有问题的,因此它非常适合自动化测试,但是如何使用playwright来进行分页自动化测试了,宏哥今天就讲解和分享一下。 2.测试场景 对分页来说,我们最感兴趣的和测试