Playwright 是微软在 2020 年初开源的新一代自动化测试工具,它的功能类似于 Selenium、Pyppeteer 等,它的功能非常强大,使用便捷简单,缺点是更新较快,市面上相关文档又少。官网:

目录

1.安装

2.初始化

3.基本使用

4.代码生成

5.选择器

6.事件监听

6.正则表达式很多时候,点击的url后面会附带参数,这个参数是变动的,这是后需要用正则去匹配最典型的情况是等待一个页面加载:page.wait_for_url(http://xxxxx?id=123456)从源码可以看出我们是可以传入正则表达式的:​编辑

7.滑动翻页

8.并发

9.实例

10.使用模板

11.使用经验


1.安装

pip install playwright -i https://pypi.tuna.tsinghua.edu.cn/simple

2.初始化

playwright install

3.基本使用

Playwright 支持两种模式:同步、异步。

同步模式:

import timefrom playwright.sync_api import sync_playwrightif __name__ == '__main__':# 浏览器上下文管理器with sync_playwright() as p:# 启动谷歌浏览器(关闭无头模式)driver = p.chromium.launch(headless=False)# 新建页面page = driver.new_page()# 访问网址page.goto('https://www.baidu.com')print(page.title())page.fill('xpath=//input[@id="kw"]', '杜兰特')page.click('xpath=//input[@id="su"]')# 关闭驱动time.sleep(5)driver.close()

异步模式:

import asynciofrom playwright.async_api import async_playwrightasync def main():# 浏览器上下文管理器async with async_playwright() as p:# 启动谷歌浏览器(关闭无头模式)driver = await p.chromium.launch(headless=False)# 新建页面page = await driver.new_page()# 访问网址await page.goto('https://www.baidu.com')title = await page.title()print(title)# 关闭驱动await driver.close()asyncio.run(main())

注意:with 用于上下文对象的管理,它可以返回一个上下文管理器,也就对应一个 PlaywrightContextManager 对象,无论运行期间是否抛出异常,它能够帮助我们自动分配并且释放 Playwright 的资源。

4.代码生成

Terminal执行:

playwright codegen -o script.py

操作浏览器后,右边会生产相应的代码预览

关闭浏览器后,会在同级目录生成script.py代码 ,可以直接执行。

5.选择器

import timefrom playwright.sync_api import sync_playwrightif __name__ == '__main__':# 浏览器上下文管理器with sync_playwright() as p:# 启动谷歌浏览器(关闭无头模式)driver = p.chromium.launch(headless=False)# 新建页面page = driver.new_page()# 访问网址page.goto('https://www.baidu.com')print(page.title())# xpath选择器(推荐,不同的模拟器有不同的写法,但是xpath都是相通的,一招鲜吃遍天)page.fill('xpath=//input[@id="kw"]', '杜兰特')# ID选择器page.click('#su')time.sleep(2)# class选择器page.fill('.s_ipt', '欧文')# 文本选择器page.click('text=百度一下')# 关闭驱动time.sleep(2)driver.close()

6.事件监听

Page 对象提供了一个 on 方法,它可以用来监听页面中发生的各个事件,比如 close、console、load、request、response 等等。一个典型的用法就是用来监听页面的ajax请求响应:

import time
import cchardet
from playwright.sync_api import sync_playwright, Response# 监听Response回调函数
def handle_response(response: Response):detect = cchardet.detect(response.body())if detect['encoding']:print(response.body().decode(detect['encoding']))if __name__ == '__main__':# 浏览器上下文管理器with sync_playwright() as p:# 启动谷歌浏览器(关闭无头模式)driver = p.chromium.launch(headless=False)# 新建页面page = driver.new_page()# 访问网址page.goto('https://spa6.scrape.center/')print(page.title())# 监听网络请求的Responsepage.on('response', handle_response)# 等待网络请求加载完毕page.wait_for_load_state('networkidle')time.sleep(2)driver.close()

6.正则表达式
很多时候,点击的url后面会附带参数,这个参数是变动的,这是后需要用正则去匹配
最典型的情况是等待一个页面加载:page.wait_for_url(http://xxxxx?id=123456)
从源码可以看出我们是可以传入正则表达式的:

使用示例:

page.wait_for_url(re.compile("https://www.abcd.xyz/web/index[\s\S]*"))

7.滑动翻页

page.locator("body").press("PageDown")

8.并发

import asyncio
import timefrom playwright.async_api import async_playwrightasync def run(url):async with async_playwright() as playwright:# create a chromium browser instancechromium = playwright.chromium# browser = await chromium.launch()# create a bowser instance which headless is truebrowser = await chromium.launch(headless=False)# create two isolated browser contextsuser_context = await browser.new_context()page = await user_context.new_page()await page.goto(url)await page.fill('xpath=//input[@id="kw"]', '杜兰特')await page.click('xpath=//input[@id="su"]')time.sleep(10)# await page2.goto('https://www.baidu.com')async def main():tasks = []urls = ['https://www.baidu.com', 'https://www.baidu.com', 'https://www.baidu.com']for url in urls:task = asyncio.ensure_future(run(url))tasks.append(task)await asyncio.gather(*tasks)if __name__ == '__main__':asyncio.run(main())

9.实例

"""
同步模式
"""
import timefrom playwright.sync_api import sync_playwright, Page, Locatordef handle_business(page: Page, url):"""逻辑处理:param page: 页面实例:param url: 访问地址:return:"""page.goto(url)# 定位输入框"""定位!1.xpath定位:【搜索框】locator_input = page.locator('xpath=//input[@id="kw"]')2.元素属性定位:【搜索框】locator_input = page.locator('[name="wd"]')后者locator_input = page.locator('[class="s_ipt"]')3.本文定位:【搜索按钮】locator_submit_button = page.locator('text="百度一下"')4.id定位:【搜索按钮】locator_submit_button = page.locator('#su')5.CSS定位:略6.伪类①:is【如果定位不到text="百度一下",则定位#su】locator_submit_button = page.locator(':is([text="百度一下"]),#su')7.伪类②:has8.伪类③:hans-text"""locator_input = page.locator('[class="s_ipt"]', ).filter()"""页面操作!1.page.goto("https://example.com") # 前往页面2.page.go_back(**kwargs) #前进3.page.go_forward(**kwargs) # 后退4.page.screenshot(path="screenshot.png") 截图5.print(page.title()) # 打印当前页标题6.print(page.url()) # 打印当前页URL7.page.reload(**kwargs) # 重新加载当前页面"""# 填写locator_input.fill('SpringBoot')# 定位提交按钮locator_submit_button: Locator = page.locator(':is([text="百度一下"]),#su')# 鼠标单击locator_submit_button.click()"""等待元素!1.等待元素:page.wait_for_selector(selector="[class='page-item_M4MDr pc']", strict=False, state="visible", timeout=5000)state:- `attached` - 等待元素出现在DOM中- `detached` - 等待元素消失在DOM中- `visible` - 等待元素可访问- `hidden` - 等待元素隐藏strict:断言选择器元素唯一。2.等待固定时间:page.wait_for_timeout(1000)3.等待状态:page.wait_for_load_state(state="networkidle")state:- `domcontentloaded` - 等待DOM加载完毕- `load` - 等待加载事件完毕- `networkidle` - 等待网络闲置至少500ms(即网络加载完毕)"""page.wait_for_load_state(state="networkidle")"""元素操作!1.文本输入:locator_input.fill('SpringBoot')2.获取节点属性:attribute = page.get_attribute("#su", "type")3.点击:locator_submit_button.click()或者page.click("#su")"""time.sleep(50)if __name__ == '__main__':# 浏览器上下文管理器with sync_playwright() as p:# 创建浏览器驱动browser = p.chromium.launch(headless=False)# 创建浏览器实例context = browser.new_context()# 创建页面实例page = context.new_page()handle_business(page, 'https://www.baidu.com/')

10.使用模板

import timefrom playwright.sync_api import sync_playwrightif __name__ == '__main__':# 浏览器上下文管理器with sync_playwright() as p:# 启动谷歌浏览器(关闭无头模式)driver = p.chromium.launch(headless=False, args=["--start-maximized"])# 全屏context = driver.new_context(no_viewport=True)# 新建页面page = context.new_page()# 这里使用生成器生成!!!!TODO# 关闭驱动time.sleep(10)context.close()driver.close()

11.使用经验

①最好不要去手写,太影响效率,最好是使用生成器,然后复制进模板进行修改。

②生成器生成的代码,往往无法直接使用,因为很多定位器是动态的,无法使用,我们需要把动态的定位器换成固定的定位器。

③有些元素只有悬停才会出现,我们可以使用hover()

page1.get_by_role("link", name="系统维护").hover()

④有些元素找不到、定位不到,可能是加载太慢了,我们可以先用xpath定位,等待元素出现

# 先等待元素
page1.wait_for_selector(selector='//div[@class="am-modal-dialog" and @style="width: 540px; height: 150px;"]//span[@class="am-modal-btn"]')
# 再获取元素selector = page1.query_selector(selector='//div[@class="am-modal-dialog" and @style="width: 540px; height: 150px;"]//span[@class="am-modal-btn"]')
# 最后操作元素selector.click()

⑤在循环里面做好异常捕获,并在捕获中将界面打回新一轮的起点。

⑥有时候跑得太快,下拉框没有选择进去,可以多执行几次。

page1.frame_locator("iframe[style=\"min-height:322px\"]").locator("select[name=\"orgCategory\"]").select_option(f"{number}")
page1.frame_locator("iframe[style=\"min-height:322px\"]").locator("select[name=\"orgCategory\"]").select_option(f"{number}")
page1.frame_locator("iframe[style=\"min-height:322px\"]").locator("select[name=\"orgCategory\"]").select_option(f"{number}")
page1.get_by_text("确定").click()

Scrapy第十五篇:后起之秀-Playwright相关推荐

  1. 坚持的力量 第十五篇

    第十五篇        漩涡鸣人 从他身上,我看到了进步和向上的力量,经别人推荐,我发现我渐渐的喜欢上了<火影忍者>. 首先,<火影>中的歌曲很有震撼力和穿透力,产生心灵的共鸣 ...

  2. 秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题

    秒杀多线程第十五篇 关键段,事件,互斥量,信号量的"遗弃"问题 在<秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量>中对经典多线程同步互斥问题进行了回 ...

  3. CCIE理论-第十五篇-IPV6-重分布+ACL+前缀列表

    CCIE理论-第十五篇-IPV6-重分布+ACL+前缀列表 重分布前面讲过,这里再讲一次+实操+效果看看 在ipv6中重分布直连路由是需要加上include-connected的 环境 就这么简单哈, ...

  4. CCIE-LAB-第十五篇-IPV6-BGP+VPN6+RT

    CCIE-LAB-第十五篇-IPV6-BGP+VPN6+RT 实际中,思科只会给你5个小时去做下面的全部配置 这个是CCIE-LAB的拓扑图 问题 翻译: 根据这些要求,将IPV6连接从总部通过SP扩 ...

  5. CCNP-第十五篇-VXLAN(一)

    CCNP-第十五篇-VXLAN(一) 到了这个阶段呢,怎么说呢,简单的NP级别的交换我都跳过去了,但是后期会补, 所以这个衔接可能新手或者不会的看的有的迷茫 但是出自个人原因只好这么干了,VXLAN3 ...

  6. CCNA-第十五篇-DHCP配置+SDN介绍(最后一章)

    CCNA-第十五篇-DHCP配置+SDN介绍 各位好,如果有一直看下来的谢谢支持 这里是CCNA的最后一篇了,如果真的能吸收很多内容,那么普通的东西基本上都没什么大问题了.除非就是工作经验 下一篇就到 ...

  7. python连载第十五篇~史上最全列表知识源码+答案

    #2017-12-19 19:34:41 December Tuesday the 51 week, the 353 day #python连载第十五篇~list列表#列表定义,访问,索引,操作,切片 ...

  8. Python之路【第十五篇】:Web框架

    Python之路[第十五篇]:Web框架 Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 7 ...

  9. 第七十五篇:学术论文写作技巧

    第七十五篇:学术论文写作技巧 论文写作技巧 下载 论文写作技巧 最近听了一下网课,把大牛们的论文讲课记录和网上一些关于论文写作技巧的文章总结了一下.总结了一些关于论文的润色.语法.投稿.回复审稿人等需 ...

最新文章

  1. 深度学习 dns tunnel检测 使用统计特征 全连接网络——精度99.8%
  2. session_start() [function.session-start]
  3. php百合网,来百合网直播,做最真实的自己
  4. java设计一个bank类实现银行_AOS公链推出“隐私Bank”,彻底打破资产发行门槛!...
  5. android camera滑动,Android怎么实现小米相机底部滑动指示器
  6. oracle11g创建表空间大文件,oracle11g创建表空间 sql语法
  7. 巴西政府考虑用微软产品替换开源软件
  8. ios更新了系统无服务器,iPhone更新iOS 12.0.1系统失败怎么办?
  9. Hive insert into小文件问题
  10. 休宁天气预报软件测试,【休宁天气预报】休宁今天天气预报 - 天气史
  11. SSM框架02--mybatis(1)
  12. 主动轮廓模型snake
  13. 100套法律合同范本,赶快收藏以后签合同心里就有谱了
  14. 中国的程序员工资为什么那么高?
  15. 利用学信网免费激活PyCharm企业版(也适用所有其它JetBrains的IDE)
  16. matter.js学习笔记(八)--Composites.newtonsCradle()制造牛顿摆
  17. oracle spatial特点,Oraclespatial结构取讲解
  18. mysql本机地址_mysql连接时用的IP地址是不是电脑本机上的IP地址呢!
  19. Android点击打开微信
  20. 解忧杂货铺----读后感

热门文章

  1. Emun 枚举类型使用浅析——包括enumSet enumMap
  2. 平面内有N个点,如何快速求出距离最近的点对?
  3. 网络协议分析(最全)
  4. centos 6.5升级内核到3.10
  5. 联发科与晨星合并诞生新寨主
  6. html手机下拉菜单样式,MUI下拉菜单样式
  7. (通俗易懂)极大元,极小元,最大元,最小元,上界,下界,上确界,下确界
  8. 这样解决浏览器不兼容问题
  9. jmeter非GUI输出性能测试报告报WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x
  10. Nasdaq股票代码表 zt