找回密码
 会员注册
查看: 17|回复: 0

Python高效的Web自动化测试利器—Python+Playwright快速上手自动化实战指南

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
69864
发表于 2024-9-10 05:50:24 | 显示全部楼层 |阅读模式
文章目录前言一.playwright是什么二.python引入playwright1.安装2.playwright命令行参数3.playwrightcodegen自动生成代码4.Chrome和Chromium有什么关系?三.基本概念1.无头浏览器(HeadlessBrowser)2.同步和异步模式操作playwright2.1.同步(Sync)模式同步方式代码模板2.2.异步(Async)模式异步方式代码模板3.Browser(浏览器驱动)4.Context(浏览器上下文)5.Page页面(浏览器标签页)四.页面元素定位1.locator选择器1.文本选择器2.css选择器和Xpath定位3.组合定位:text、css、xpath三者可以两组合定位2.playwright推荐的内置定位——get_by3.html5的role属性与get_by_role五.浏览器操作1.Textinput文本输入2.Checkboxesandradiobuttons单选和多选3.Selectoptions下拉选择4.Click鼠标单击和双击5.Press按下指定的键6.Focus聚焦7.DargandDrop拖拉8.鼠标移动到指定的locator上9.运行JS脚本10.文件上传11.页面事件监听12.获取元素文本六.断言七.浏览器常见配置1.截图1.1.截图整个页面1.2.截取整个页面并裁剪2.设置窗口(Viewport)大小4.截取特定元素并调整大小5.捕获截图为字节流2.自定义Header3.自定义UserAgent4.设置浏览器代理1.启动时设置全局代理2.上下文设置代理5.自动等待机制1.自动等待和##可操作性校验(Auto-waiting)2.显式等待API(ExplicitWaiting)3.全局设置等待超时时间6.处理新的窗口、弹窗,iframe7.支持Pytest框架8.移动端浏览器支持八.playwright如何绕过反爬虫检测1防止webdriver属性被检测2headless=True无头浏览器如何绕过反爬虫3.stealth.min.js作用4.防止爬虫检测的方式九.通过CDP(ChromeDevToolsProtocol)连接现有浏览器1.CDP(ChromeDevToolsProtocol)和WDP(WebDriverProtocol)协议2.WebDriverProtocol3.ChromeDevToolsProtocol4.WebDriverProtocol和ChromeDevToolsProtocol对比5.通过CDP控制本地原生谷歌浏览器十.拓展知识屏幕坐标系,世界坐标系十一.Playwright和Selenium的区别前言本教程旨在引导读者从零开始,逐步掌握使用Python和Playwright进行Web自动化测试的技能。无论你是初涉自动化测试的开发者,还是希望提升现有测试框架效能的资深测试工程师,本教程都将为你提供丰富的实战案例、详细的步骤解析以及最佳实践分享。一.playwright是什么Playwright是微软在2020年初开源自动化测试工具,功能和selenium类似,都可以驱动浏览器进行各种自动化操作。支持主流浏览器,如Chrome、Firefox、Safari等,同时支持以无头模式、有头模式运行,并提供了同步、异步的API,可以结合主流测试框架使用,并且支持浏览器端的自动化脚本录制等功能。特点:跨浏览器:Playwright支持所有现代渲染引擎,包括Chromium、WebKit和Firefox;跨平台:在Windows、Linux和MacOS上进行本地或CI、无头或有头测试;跨语言:在TypeScript、JavaScript、Python、.NET、Java中使用PlaywrightAPI;测试移动网络:适用于Android和MobileSafari的GoogleChrome原生移动仿真。相同的渲染引擎适用于您的桌面和云端。官网:https://playwright.dev/官方文档github项目地址:https://github.com/microsoft/playwright-pythonPython文档PythonAPI文档其他鼎鼎大名的selenium、Pyppeteer、DrissionPage等。推荐原因:运行playwrightcodegen命令可自动自动生成代码,降低编写爬虫代码的门槛和难度,不用自己逐个去分析页面代码结构playwright微软是从2020年开始创建的项目,更新稳定且频率不低,可长期使用一个库或框架代码结构清晰,功能齐全,门槛低支持多个语言版本:python、Node.js、Java、.net,原生支持同步异步两种方式**自动等待pw在做某个操作之前需要有一个前提条件成立才进行,系统会自动等待检查通过,直到超时。比如我要系统自动点击某个元素,那么playwright会自动:1.等待指定选择器的元素出现在DOM中(不用自己去写轮询等待了)2.等待它显示出来,即不为空,不为display:none,不为visibility:hidden(这个太人性化了,不用去判断元素是否隐藏)3.等待它停止移动,例如,直到css转换完成4.将元素滚动到视图中(这个太人性化了,不用自己去滚动了)5.等待它在动作点接收指针事件,例如,等待直到元素变得不被其他元素遮挡如果元素检测到上述任何场景,则重试二.python引入playwright1.安装安装playwright-python依赖库(需要注意的是,playwright库需要依赖Python3.7+以上)可在https://pypi.org/project/playwright/查看它的依赖版本信息。pipinstallplaywright1官网推荐pipinstallpytest-playwright来安装,但没必要,会安装playwright及其他一堆测试所用的库,如果只是使用playwright,那么就没必要这样去安装。自动下载使用的浏览器playwrightinstall1执行命令以后,会自动下载chromium、firefox以及webkit三种浏览器,存放文件夹路径为(windows环境):c:\Users\YOURUSERNAME\AppData\Local\ms-playwright\1以上三种浏览器分别对应三种不同内核的浏览器,在爬虫过程中可以自定义选择任意一种浏览器2.playwright命令行参数想查看Playwright支持的功能,可在命令行输入:playwrighthelp1Usage:index[options][command]Options:-V,--versionoutputtheversionnumber-b,--browser browsertouse,oneofcr,chromium,ff,firefox,wk,webkit(default:"chromium")--color-schemeemulatepreferredcolorscheme,"light"or"dark"--deviceemulatedevice,forexample"iPhone11"--geolocationspecifygeolocationcoordinates,forexample"37.819722,-122.478611"--langspecifylanguage/locale,forexample"en-GB"#设置代理--proxy-server specifyproxyserver,forexample"http://myproxy:3128"or"socks5://myproxy:8080"--timezonetimezonetoemulate,forexample"Europe/Rome"--timeouttimeoutforPlaywrightactionsinmilliseconds(default:"10000")#设置user-agent--user-agentspecifyuseragentstring#设置浏览器打开窗口的大小--viewport-sizespecifybrowserviewportsizeinpixels,forexample"1280,720"-h,--helpdisplayhelpforcommandCommandspen[url]openpageinbrowserspecifiedvia-b,--browsercr[url]openpageinChromiumff[url]openpageinFirefoxwk[url]openpageinWebKitcodegen[options][url]openpageandgeneratecodeforuseractionsscreenshot[options]captureapagescreenshotpdf[options]savepageaspdfinstallEnsurebrowsersnecessaryforthisversionofPlaywrightareinstalledhelp[command]displayhelpforcommand12345678910111213141516171819202122232425262728293031323334353.playwrightcodegen自动生成代码在命令行输入下面代码会自动弹出一个浏览器和一个代码编辑器在该浏览器上每一步操作都会自动生成到代码编辑器上,可复制使用playwrightcodegenhttps://www.baidu.com/-oscript.py1查看录制脚本的命令说明playwrightcodegen--help1Usage:indexcodegen[options][url]openpageandgeneratecodeforuseractionsOptions:#生成自动化脚本路径-o,--outputsavesthegeneratedscripttoafile#–target脚本语言,包含JS和Python,分别对应值为:python和javascript--targetlanguagetouse,oneofjavascript,python,python-async,csharp(default:"python")#帮助文档-h,--helpdisplayhelpforcommandExamplescodegen$codegen--target=python#指定浏览器驱动$-bwebkitcodegenhttps://example.com123456789101112131415161718如要在baidu.com搜索,用chromium驱动,将结果保存为mikezhou.py的python文件。playwrightcodegen--targetpython-o'mikezhou.py'-bchromiumhttps://www.baidu.com1命令行输入后会自动打开浏览器,然后可以看见在浏览器上的一举一动都会被自动翻译成代码,如下所示:最后,自动化脚本会自动生成,保存到文件中mikezhou.py,且上述所有的人工操作,都会被自动转化成代码:fromplaywrightimportsync_playwrightdefrun(playwright):browser=playwright.chromium.launch(headless=False)context=browser.newContext()#Opennewpagepage=context.newPage()#Gotohttps://www.baidu.com/page.goto("https://www.baidu.com/")#Clickinput[name="wd"]page.click("input[name=\"wd\"]")#Fillinput[name="wd"]page.fill("input[name=\"wd\"]","禾目大")#PressCapsLockpage.press("input[name=\"wd\"]","CapsLock")#Fillinput[name="wd"]page.fill("input[name=\"wd\"]","自动化测试实战宝典")#PressEnterpage.press("input[name=\"wd\"]","Enter")#assertpage.url()=="https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95%E5%AE%9E%E6%88%98%E5%AE%9D%E5%85%B8%20&fenlei=256&rsv_pq=af40e9aa00012d5a&rsv_t=c659gpz2%2Fjri1SAoIXdT9gP%2BmrqufXzRtMSSAL0n0fv7GSoLF5vaiNVPA3U&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=38&rsv_sug1=22&rsv_sug7=100&rsv_sug2=0&rsv_btype=i&inputT=8034&rsv_sug4=9153"#Closepagepage.close()#---------------------context.close()browser.close()withsync_playwright()asplaywright:run(playwright)12345678910111213141516171819202122232425262728293031323334353637384.Chrome和Chromium有什么关系?可看做同一个项目下的两个分支,chromium是测试开源版,所有的功能都会先在其身上测试,确定稳定运行后再移植到chrome上,而chrome是Google正式商业版浏览器,两者由Google官方和chromium社区进行维护三.基本概念1.无头浏览器(HeadlessBrowser)HeadlessBrowser俗称的无头浏览器,实际上就是没有图形界面的浏览器,因为省去了视觉渲染的工作,性能和开销有较大优化,粗略估计,原本只能启动十个浏览器的内存,使用Headless模式可以至少启动三倍的数量无头浏览器应用场景无浏览器UI,运行速度较快,常用于自动化运行有浏览器UI,常用于调试代码Playwright支持以无头模式(HeadlessBrowser)执行自动化测试,这样就不会实际打开可见的浏览器窗口。无头模式对于持续集成(CI)、后台执行测试或在没有图形界面的服务器环境中运行测试非常有用在使用Playwright的无头浏览器模式(‌headless=True)‌时遇到找不到元素的问题可能是网站反爬虫机制或User-agent参数问题导致的。‌常见的反爬虫手段是通过检测当前user-agent是否为真实浏览器来区分当前请求是否来自真实用户。爬虫使用的常见user-agent类型为:user-agent为空。没有设置user-agent。user-agent中包含特殊字符。如:python,java,bot,spider,headless等。而使用Playwright的Chrome无头浏览器访问网站时,user-agent中会自动添加Headless字段。当网站检测到user-agent包含Headless时判定为非真实请求时,可能会返回空页面,所以导致无头浏览器找不到元素。用浏览器到https://www.useragentstring.com/index.php查看当前浏览器使用的UserAgentString,在Playwright配置中设置自定义的User-agent#通过args设置browser=playwright.chromium.launch(headless=True,args=['--user-agent=Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/114.0.0.0Safari/537.36'])#通过上下文设置context=browser.new_context(no_viewport=True,user_agent="Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/127.0.0.0Safari/537.36")12342.同步和异步模式操作playwright2.1.同步(Sync)模式在同步模式下,代码按照从上到下的顺序执行。每个操作都会阻塞直到完成,然后再执行下一行代码。这意味着在等待某个操作(如页面加载)完成之前,程序不会继续往下执行。关键字:sync_playwright对于初学者或习惯于同步编程模型的开发者来说,同步模式可能更加直观和易于理解,因为它遵循了传统的线性编程逻辑。#导入Playwright类和sync_palywright同步类fromplaywright.sync_apiimportsync_playwright#-------------------------写法1withsync_playwright()asplaywright:browser=playwright.chromium.launch(headless=False)#启动chromium浏览器context=browser.new_context()#打开一个上下文page=context.new_page()#打开一个标签页page.goto("https://www.baidu.com")#打开百度地址print(page.title())#打印当前页面titlecontext.close()browser.close()#关闭浏览器对象#-------------------------写法2#如果不习惯with语句,也可以用start()和stop()的方式:defmain(playwright):browser=playwright.chromium.launch(headless=False)context=browser.new_context()page=context.new_page()page.goto("https://www.baidu.com/")print(page.title())context.close()browser.close()withsync_playwright()asplaywright:main(playwright)1234567891011121314151617181920212223242526同步方式代码模板fromplaywright.sync_apiimportPlaywright,sync_playwright,expectdefmain(playwrightlaywright)->None:"""这是一个名为main的函数定义,它接受一个名为playwright的参数,该参数被类型注解为Playwright(这表明playwright应该是一个Playwright实例,但注意Python本身不强制类型注解,这是为了代码可读性和工具支持)。函数没有返回值(->None表示返回类型为None)。"""browser=playwright.chromium.launch(headless=False)context=browser.new_context()page=context.new_page()###################这里将是操作页面的代码块################## #**完整的playwright流程** #1.创建browser(浏览器实例) #2.创建context(共cookie、session) #3.创建page(具体选项卡页面),然后用页面去模拟操作 #4.完成所有的操作后关闭之前创建的三种对象。pass#############################################################page.close()context.close()browser.close()withsync_playwright()asplaywright:main(playwright)1234567891011121314151617181920212223242526272.2.异步(Async)模式异步模式利用Python的asyncio库,允许非阻塞的并发操作。可以在等待某个耗时操作(如网络请求)的同时,程序可以继续执行其他任务。你需要使用await关键字来等待异步操作的结果。关键字为:async_playwright,异步操作可结合asyncio同时进行三个浏览器操作。效率:异步模式能显著提高脚本的执行效率,特别是在进行大量网络请求或需要同时管理多个页面/浏览器实例的场景下。因为它能够更好地利用系统资源,减少闲置时间。比我想爬取300章小说,如果用单线程去爬,那么时间是线性的,爬取每一章节所使用的时间积累起来就是最终所用的总时间;如果用多线程,比如说同时用10个线程去爬,那么理论上总时间就是单线程所用时间的1/10。相反,如果我只是想获取某一个页面的内容,那么直接单线程就完事复杂度:相比同步模式,异步编程模型引入了额外的概念,如协程(coroutine)、事件循环(eventloop)等,这可能会增加代码的复杂度,尤其是对于不熟悉异步编程的开发者而言。importasynciofromplaywright.async_apiimportPlaywright,async_playwright#写法1withasync_playwright()asplaywright:browser=awaitplaywright.chromium.launch(headless=False)#启动chromium浏览器context=awaitbrowser.new_context()#打开一个上下文page=awaitcontext.new_page()#打开一个标签页awaitpage.goto("https://www.baidu.com")#打开百度地址print(awaitpage.title())#打印当前页面titleawaitcontext.close()awaitbrowser.close()#写法2如果不习惯with语句,也可以用start()和stop()的方式:asyncdefmain():asyncwithasync_playwright()asplaywright:browser=awaitplaywright.chromium.launch(headless=False)context=awaitbrowser.new_context()page=awaitcontext.new_page()awaitpage.goto("https://www.baidu.com/")print(awaitpage.title())awaitcontext.close()awaitbrowser.close()asyncio.run(main())12345678910111213141516171819202122232425例如:importasynciofromplaywrightimportasync_playwright#异步执行asyncdefmain():asyncwithasync_playwright()asp:forbrowser_typein[p.chromium,p.firefox,p.webkit]:#指定为有头模式,方便查看browser=awaitbrowser_type.launch(headless=False)page=awaitbrowser.new_page()awaitpage.goto('http://baidu.com')#执行一次搜索操作awaitpage.fill("input[name=\"wd\"]","自动化测试实战宝典")awaitpage.press("input[name=\"wd\"]","Enter")#等待页面加载完全awaitpage.wait_for_selector("text=搜索工具")#截图awaitpage.screenshot(path=f'test-{browser_type.name}.png')awaitbrowser.close()asyncio.get_event_loop().run_until_complete(main())1234567891011121314151617181920212223242526异步方式代码模板importasynciofromplaywright.async_apiimportPlaywright,async_playwright,expectasyncdefrun(playwrightlaywright)->None:browser=awaitplaywright.chromium.launch(headless=False)context=awaitbrowser.new_context()page=awaitcontext.new_page()#########################操作页面的代码块##############**完整的playwright流程** #1.创建browser(浏览器实例) #2.创建context(共cookie、session) #3.创建page(具体选项卡页面),然后用页面去模拟操作 #4.完成所有的操作后关闭之前创建的三种对象。pass####################################################awaitpage.close()awaitcontext.close()awaitbrowser.close()asyncdefmain()->None:asyncwithasync_playwright()asplaywright:awaitrun(playwright)asyncio.run(main())12345678910111213141516171819202122232425262728293.Browser(浏览器驱动)对应一个浏览器实例(Chromium、Firefox或WebKit)支持多种浏览器:Chromium(chrome、edge)、Firefox、WebKit(Safari),一般每一种浏览器只需要创建一个browser实例。示例:#launch()方法是Playwright中用于启动浏览器的函数。它接受一个可选参数,该参数可以是一个字典,用于配置浏览器的选项。#1.创建浏览器:(这里创建的是谷歌浏览器)browser=playwright.chromium.launch(headless=False)#headless=False是有头模式,也就是代码运行时候,需要浏览器页面#(创建的是火狐浏览器)browser=playwright.firefox.launch()#关闭浏览器browser.close()12345678910browser对象常用配置项1.是否无头模式(即是否隐藏浏览器界面):headless=False#显示界面,为True时隐藏界面2.打开时最大化窗口:args=['--start-maximized']#还要配合context中设置no_viewport=True3.网络代理:proxy={"server":"http://127.0.0.1:8080",#代理服务器的地址"bypass":"*.http://bing.com",#不使用代理的域名"username":"Mike",#代理服务器的用户名"password":"123456"#代理服务器的密码}4.指定下载保存路径:downloads_path=r"d:\"5.viewport:字典,用于指定浏览器窗口的大小和位置。例如:{'width':800,'height':600}。6.slow_mo:浮点数,默认为0。如果设置为大于0的值,则会增加浏览器操作的延迟时间(单位为毫秒)。7.ignore_https_errors:默认为False。如果设置为True,则在访问HTTPS网站时不会检查证书错误。8.args:列表,用于传递给浏览器进程的命令行参数。例如:['--disable-gpu']1234567891011121314151617184.Context(浏览器上下文)一个浏览器实例下可以有多个context,将浏览器分割成不同的上下文,以实现会话的隔离,如需要不同用户登录同一个网页,不需要创建多个浏览器实例,只需要创建多个context即可可以理解为轻量级的浏览器实例.如需要不同用户登录同一个网页,不需要创建多个浏览器实例,只需要创建多个context即可。浏览器上下文,相当于一个全新的浏览器配置文件,提供了完全的测试隔离,并且零开销。创建一个新的浏览器上下文只需要几毫秒,每个上下文都有自己的Cookie、浏览器存储和浏览历史记录。浏览器上下文允许同时打开多个页面并与之交互,每个页面都有自己单独的状态,一个BrowserContext可以包含多个Page#new_context()方法是Playwright库中用于创建一个新的浏览器上下文的函数。它接受一个可选参数,该参数可以是一个字典,用于配置浏览器上下文的选项#1.创建浏览器上下文context=browser.new_context()#2.关闭context.close()12345Context相关常用配置项1.no_viewport=True:最大化窗口(与browser的args联合使用)2.java_script_enabled=False:禁用javascript:3.viewport:字典,用于指定浏览器窗口的大小和位置。例如:{'width':800,'height':600}。4.忽略https错误:ignore_https_errors=True5.user_agent:字符串,默认为当前浏览器的用户代理字符串。如果设置为其他值,则会使用指定的用户代理字符串。6.accept_downloads:布尔值,默认为False。如果设置为True,则会在下载文件时自动接受下载对话框。7.record_har:字典,用于录制HTTP请求和响应数据。例如:{'path':'/tmp/har.har'}。8.其他配置device_scale_factor:浮点数,指定设备缩放比例,例如1.5。如果不指定,则使用默认的设备缩放比例。is_mobile:布尔值,指定是否模拟移动设备,默认为False。has_touch:布尔值,指定是否支持触摸事件,默认为False。bypass_csp:布尔值,指定是否绕过内容安全策略,默认为False。locale:字符串,指定浏览器的语言和地区,例如“en-US”或“zh-CN”。如果不指定,则使用默认的语言和地区。timezone_id:字符串,指定浏览器的时区,例如“Asia/Shanghai”或“America/New_York”。如果不指定,则使用默认的时区。geolocation:字典,指定浏览器的地理位置,包括latitude(纬度),longitude(经度)和accuracy(精度),例如{“latitude”:31.2304,“longitude”:121.4737,“accuracy”:10}。如果不指定,则使用默认的地理位置。permissions:列表,指定浏览器的权限,例如[“geolocation”,“notifications”,“camera”]。如果不指定,则使用默认的权限。extra_http_headers:字典,指定浏览器的额外HTTP头部,例如{“x-foo”:“bar”}。如果不指定,则使用默认的HTTP头部。offline:布尔值,指定是否模拟离线状态,默认为False。http_credentials:字典,指定浏览器的HTTP认证,包括username(用户名)和password(密码),例如{“username”:“admin”,“password”:“123456”}。如果不指定,则使用默认的HTTP认证。color_scheme:字符串,指定浏览器的配色方案,可以是“dark”或“light”。如果不指定,则使用默认的配色方案。record_video:字典,指定是否录制浏览器的视频,包括dir(视频保存的目录)和size(视频的宽度和高度),例如{“dir”:“videos/”,“size”:{“width”:800,“height”:600}}。如果不指定,则不录制视频。proxy:字典,指定代理设置,包括server(代理服务器地址),bypass(要绕过代理的域名列表),username(代理用户名),password(代理密码)1234567891011121314151617181920212223context常用方法context.pages:获取context所有page对象context.new_page():生成一个新的page对象context.close():关闭contextcontext.add_cookies():将cookie添加到此浏览器上下文中。此上下文中的所有页面都将安装这些cookie。只能传入列表List[{name:str,value:str,url:Union[str,None],domain:Union[str,None],path:Union[str,None],expires:Union[float,None]context.clear_cookies():清除context的cookiecontext.grant_permissions():授予浏览器上下文的指定权限,具体见apicontext.clear_permissions():清除授权1234567895.Page页面(浏览器标签页)一个context下可以有多个page,一个page就代表一个浏览器的标签页或弹出窗口,用于进行页面操作。这个也是我们主要操作的对象。后续打开网页、定位元素、页面操作都是基于page#1.创建一个新的浏览器页面page=context.new_page()#2.打开一个网页page.page.goto(url,**kwargs) #默认是在当前tab打开page.goto(url)如果你想要在同一个上下文中打开多个页面,重新创建page即可 #url就是网址,需要包含访问协议,比如https://www.bing.com #**kwargs包括: #timeout=10000#可选项,单位ms,超时时间,默认30秒,设为0则永不超时 #wait_until='load'#可选项,等待页面状态符合指定值,默认为load,具体解释参加下方内容#3.关闭page.close()#4.获取当前页面的URLpage.url#5.在页面上执行JavaScript代码page.evaluate('()=>document.title')#6.截取页面的屏幕截图page.screenshot(path='screenshot.png')123456789101112131415161718asyncdefnew_page(self,viewport:ViewportSize=None,#为每个页面设置一致的窗口。默认为1280x720窗口screen:ViewportSize=None,#通过“window.screen”模拟网页内可用的一致窗口屏幕大小,只能在viewport设置之后使用noViewport:bool=None,#不强制固定窗口,允许在模式下调整窗口大小ignoreHTTPSErrors:bool=None,javaScriptEnabled:bool=None,#禁用javaScriptbypassCSP:bool=None,userAgent:str=None,#设置代理用于上下文locale:str=None,#指定用户区域,设置将影响Accept-Language'请求标头值以及数字和日期格式规则timezoneId:str=None,#设置时区geolocation:Geolocation=None,permissionsist[str]=None,extraHTTPHeadersict[str,str]=None,offline:bool=None,httpCredentials:HttpCredentials=None,deviceScaleFactor:float=None,isMobile:bool=None,#设备相关,不用管hasTouch:bool=None,colorScheme:ColorScheme=None,#Union["dark","light","no-preference","null",None]#设置颜色主题forcedColors:ForcedColors=None,#Union["active","none","null",None]reducedMotion:ReducedMotion=None,acceptDownloads:bool=None,defaultBrowserType:str=None,proxyroxySettings=None,#设置代理recordHarPath:Union[Path,str]=None,recordHarOmitContent:bool=None,recordVideoDir:Union[Path,str]=None,recordVideoSize:ViewportSize=None,storageState:Union[StorageState,str,Path]=None,baseURL:str=None,strictSelectors:bool=None,serviceWorkers:ServiceWorkersPolicy=None,recordHarUrlFilter:Union[Pattern[str],str]=None,recordHarMode:HarMode=None,recordHarContent:HarContentPolicy=None,)->age:123456789101112131415161718192021222324252627282930313233343536373839四.页面元素定位1.locator选择器locator()方法支持所有的CSS选择器`,包括:基本选择器:如div,span,.my-class,#my-id等。属性选择器:如[href],[class=“my-class”],[data-my-attr=“value”]等。伪类选择器:如:hover,:focus,:first-child,:last-of-type等。结合选择器:如div.my-class,div,span,div>p,div+p等。操作元素有两种方式先定位元素再操作元素#先定位再操作page.locator('#kw').fill("上海悠悠")page.locator('#su').click()123直接在操作元素的时候定位元素如:调用fill和click方法,传入Selector选择器**page.fill('#kw',"欧阳博客")page.click('#su')12locator()方法可以根据元素的CSS选择器来查找。您可以使用各种CSS选择器,包括但不限于:标签名:例如page.locator('button')类名:例如page.locator('.my-class')ID:例如page.locator('#my-id')属性:例如page.locator('[data-testid="my-test-id"]')文本内容:例如page.locator(':text("MyText")')12345使用locator定位元素,不管元素存不存在,都会返回一个locator对象,可以用到count()方法统计元素的个数,如果元素个数是0,那么元素就不存在locator是定位当前页面上的元素,不会自动等待,如果用click等方法结合使用,会自动去等待元素处于可点击状态。1.文本选择器文本选择器是一个非常实用的定位方式,根据页面上看到的text文本就可以定位了playwright封装了text文本定位的方式,也可以支持2种文本定位方式page.click('text=登录')没有加引号(单引号或者双引号),模糊匹配,对大小写不敏感page.click('text="登录"')有引号,精确匹配,对大小写敏感 text()查找第一个文本等于...的元素 has_text():筛选包含指定文本的元素,匹配元素内或子元素中的文本内容。 has_not_text():筛选不包含指定文本的元素。比如:.page.locator(':has_text("Playwright")').click()#也可以这样写,指定标签page.locator('article:has_text("Playwright")').click()#也可以这样page.locator(":text('Playwright')").click()#还可以这样page.locator('article:has'text=Playwright').click()page.locator("div").locator("text='Playwright'")1234567891011121314152.css选择器和Xpath定位page.locator('css=button').click()#根据标签page.locator('css=#nav-bar.contact-us-item').click()#通过id+classpage.locator('css=[data-test=login-button]').click()#属性定位page.locator("css=[aria-label='Signin']").click()page.locator(xpath="//div[@id='myId']").click()#不需要前面的前缀css=和xpath=,它会自动判断你写的是css还是xpath语法,前提是你语法没有错误。12345673.组合定位:text、css、xpath三者可以两组合定位css+text组合定位page.locator("article:has-text('Playwright')").click()page.locator("#nav-bar:text('Contactus')").click()12css+css组合定位page.locator(".item-description:has(.item-promo-banner)").click()1Xpath+css组合定位page.fill('//div[@class="SignFlow-account"]>>css=[name="username"]',"0863")1xpath+xpath组合定位page.fill('//div[@class="SignFlowInput"]>>//input[@name="password"]',"ma160065")1利用HTML元素的属性来定位,比如ID、name或其他自定义属性。page.locator("[data-testid='my-element']")1组合定位:在复杂场景下,你可能需要结合多个条件来定位元素,Playwright支持链式调用来实现这一需求。page.locator("div.container").locator("input[type='text']")12.playwright推荐的内置定位——get_byget_by_role:根据元素在页面中扮演的角色(如按钮、链接、输入框等)进行定位例如:page.get_by_role("button",name="Submit")get_by_text:通过使用文本内容来定位元素,适合于元素没有唯一标识符的情况。例如:page.get_by_text("Submit")get_by_label:根据label属性值查找元素,类似于HTML中的label标签和对应的for属性。get_by_id:通过元素的id属性来查找元素,例如:page.get_by_id("my-id")get_by_name:通过元素的name属性来查找元素,例如:page.get_by_name("my-name")get_by_title:通过元素的title属性来查找元素,例如:page.get_by_title("my-title")get_by_placeholder:通过元素的placeholder属性来查找元素,例如:page.get_by_placeholder("my-placeholder")get_by_selector:通过CSS选择器来查找元素,例如:page.get_by_selector("#submit-button")get_by_xpath:通过XPath表达式来查找元素,例如:page.get_by_xpath("//div[@class='my-class']")12345678910113.html5的role属性与get_by_rolehtml5总能role的作用是是增强html语义性,当现有的html标签不能充分表达语义性的时候,就可以借助role来说明。通常这种情况出现在一些自定义的组件上,这样可增强组件的可访问性、可用性和可交互性。role的作用是描述一个非标准的tag的实际作用。比如用div做button,那么设置div的role=“button”,辅助工具就可以认出这实际上是个button元素的role属性参考https://www.w3.org/TR/2014/REC-wai-aria-implementation-20140320/#mapping_role_tablehttp://常用role属性1.button:表示一个按钮,用于触发某个操作。2.link:表示一个链接,通常用于导航目的。3.heading:表示一个,标识文档结构。4.textbox:表示一个文本框,用户可以在其中输入文本。5.checkbox:表示一个复选框,用户可以选择或取消选择。6.radiobutton:表示一个单选按钮,用户可以从一组选项中选择一个。7.menu:表示一个菜单,用户可以从中选择一个选项。8.list:表示一个列表,可以是有序或无序的。9.progressbar:表示一个进度条,用于表示任务的进度。10.dialog:表示一个对话框,用户可以与之交互。12345678910get_by_role#元素:队列管理page.get_by_role("menuitem",name="队列管理").click()#元素:新增队列page.get_by_role("button",name="新增队列").click()12345五.浏览器操作比如:输入文本、单选、多选、选择下拉框、点击按钮/文本、按下某个按键、上传文件、元素对应焦点、鼠标的拖拽、执行JS脚本等等。1.Textinput文本输入对应的是input、textarea、contenteditable等元素locator=page.get_by_label("Password")locator.fill("mypassword")#输入一段文字locator.fill("type")#一个字符一个字符地输入232.Checkboxesandradiobuttons单选和多选locator=page.get_by_label('Iagreetothetermsabove')locator.check()123.Selectoptions下拉选择locator=page.get_by_label('Chooseacolor')locator.select_option('blue')124.Click鼠标单击和双击#点击page.get_by_role("button").click()#双击page.get_by_text("Item").dblclick()#右击page.get_by_text("Item").click(button="right")#Shift+点击page.get_by_text("Item").click(modifiers=["Shift"])#鼠标悬停在元素上page.get_by_text("Item").hover()#点击左上角page.get_by_text("Item").click(position={"x":0,"y":0})12345678910111213141516175.Press按下指定的键#按Enter键page.get_by_text("Submit").press("Enter")#locator上按回车键#按ctrl+右方向键page.get_by_role("textbox").press("Control+ArrowRight")#ctrl+右方向键#按键盘上的$符合page.get_by_role("textbox").press("$")#按下$12345678上述特殊按键有:Backquote,Minus,Equal,Backslash,Backspace,Tab,Delete,Escape,ArrowDown,End,Enter,Home,Insert,PageDown,PageUp,ArrowRight,ArrowUp,F1-F12,Digit0-Digit9,KeyA-KeyZ123可以组合按下指定的键#page.locator('#name').press('Shift+A')#id为name的元素中按下shift+A#page.locator('#name').press('Shift+ArrowLeft')123456.Focus聚焦page.get_by_label('password').focus()17.DargandDrop拖拉效果是先将鼠标移动要操作的locator上,然后按住左键,移动鼠标到目标locator所在位置,松开鼠标page.locator("#item-to-be-dragged").drag_to(page.locator("#item-to-drop-at"))#将一个locator拖到另一个locator上128.鼠标移动到指定的locator上这在处理一些隐藏菜单很有效,鼠标放到菜单上后,菜单显示,然后就可以操作page.locator("#item-to-be-dragged").hover()page.mouse.down()page.locator("#item-to-drop-at").hover()page.mouse.up()12349.运行JS脚本这也是一个很有效的手段,比如某个日期输入框是只读的,无法直接录入想要的日期,只能通过日期选择框去选择,而通过日期选择框去选择效率会很低下,这个时候我们只需要通过运行JS脚本将该输入框的只读属性去掉,然后使用input方法录入日期即可#将id为txtStartDtate的元素去掉readonly属性page.evaluate('document.getElementById("txtStartDate").removeAttribute("readonly");')1210.文件上传#Selectonefilepage.get_by_label("Uploadfile").set_input_files('myfile.pdf')#page.get_by_label("Uploadfile")为一个locator,选择一个文件myfile.pdf#Selectmultiplefiles,选择多个文件page.get_by_label("Uploadfiles").set_input_files(['file1.txt','file2.txt'])#Removealltheselectedfiles,清楚选择的文件名page.get_by_label("Uploadfile").set_input_files([])#Uploadbufferfrommemorypage.get_by_label("Uploadfile").set_input_files(files=[{"name":"test.txt","mimeType":"text/plain","buffer":b"thisisatest"}],)1234567891011121314151611.页面事件监听Page对象提供了一个on方法,它可以用来监听页面中发生的各个事件,比如close、console、load、request、response等等fromplaywright.sync_apiimportsync_playwrightdefrun(playwright):chromium=playwright.chromiumbrowser=chromium.launch()page=browser.new_page()#监听请求和响应事件page.on("request",lambdarequest:print(">>",request.method,request.url))page.on("response",lambdaresponse:print("wait_for()方法和wait_for_selector()使用区别:page.locator(‘定位元素’).wait_for()返回的是None,后面不能继续操作元素page.wait_for_selector(“定位方法”)返回的是locator对象,后面可以继续操作元素wait_for_timeout(timeout):等待指定的时间。这通常用于调试目的,但在生产环境中应谨慎使用。timeout:等待的时间,单位毫秒。awaitpage.wait_for_timeout(5000)1wait_for_url(url,options)等待当前页面的URL包含指定的字符串或完全匹配指定的URL。url:要等待的URL字符串或包含部分URL的字符串。options(可选):一个对象,包含等待的选项,如timeout。awaitpage.wait_for_url('https://example.com',{timeout:10000})#等待最多10秒钟,直到当前页面的URL包含https://example.com。12wait_for_navigation(options)等待页面完成导航。options(可选):一个对象,包含等待的选项,如waitUntil(指定等待的导航状态,如’networkidle’表示等待网络请求空闲)和timeout。awaitpage.click('a.some-link')awaitpage.wait_for_navigation({waitUntil:'networkidle'})#首先点击一个链接,然后等待页面导航到新的URL,并等待直到网络请求空闲。1233.全局设置等待超时时间这些设置将影响所有接受timeout参数的方法。设置的优先级是:页面级别的优先于浏览器上下文级别。browser_context.set_default_timeout(timeout):设置浏览器上下文级别的默认超时时间。page.set_default_timeout(timeout):设置页面级别的默认超时时间。browser_context.set_default_navigation_timeout(timeout):设置浏览器上下文级别的默认导航超时时间。page.set_default_navigation_timeout(timeout):设置页面级别的默认导航超时时间。12346.处理新的窗口、弹窗,iframeselenium处理iframe比较麻烦,但是playwright就比较简单,有不同方法直接定位一个frame,在frame基础上操作#********同步*********#根据iframe名字frame=page.frame('frame-login')#根据iframe的urlframe=page.frame(url=r'.*domain.*')#Interactwiththeframeframe.fill('#username-input','John')#*********异步***********#根据iframe名字frame=page.frame('frame-login')#根据iframe的urlframe=page.frame(url=r'.*domain.*')#Interactwiththeframeawaitframe.fill('#username-input','John')12345678910111213141516171819直接定位到frame再定位到上面的元素,在元素基础上操作username=page.frame_locator('.frame-class').locator('#username-input')username.fill('jonas')12处理弹窗,一般注册、或者点击一些按钮容易出现弹窗,我们可以利用page.expect_popup()来获取新窗口的iframe示例:withpage.expect_popup()aspopup_info:#iframe中的id如果是动态的,所以我们只匹配关键字page.frame_locator("iframe[id^=x-URS-iframe]").locator("text=注册新帐号").click()register_page=popup_info.value#点击邮箱地址输入框register_page.locator("input[id=\"username\"]").click()#输入邮箱register_page.locator("input[id=\"username\"]").fill("TesterRoad")#点击密码输入框register_page.locator("input[id=\"password\"]").click()#输入密码register_page.locator("input[id=\"password\"]").fill("TesterRoad@126")12345678910111213手动设置等待是为了确保接下来的操作可以成立,旧版本里使用了很多类似wait_for_selector的用法,但新版本推荐使用的是expect方法,就是期望某个条件成立,默认超时时间为5秒7.支持Pytest框架另外,还可以配合pytest插件一起使用,给出一段官网示例:#导入pytest和playwright的sync_api(也可以使用async_api)importpytestfromplaywright.sync_apiimportPage#使用pytest的fixture来初始化浏览器页面@pytest.fixture(scope="function")defpage(browser_type):"""启动浏览器并创建一个新页面"""browser=browser_type.launch(headless=False)#如果想看到浏览器运行,可以设置为Falsepage=browser.new_page()yieldpage#测试函数将在这里接收page对象browser.close()#测试完成后关闭浏览器#编写测试函数deftest_example(page):"""示例测试:访问Playwright官网并验证"""#导航到Playwright官网page.goto("https://playwright.dev/")#验证页面是否包含"Playwright"title=page.title()assert"Playwright"intitle#进一步的操作,比如点击链接、填写表单等#...#注意:上述代码中的browser_type是由pytest-playwright插件自动提供的fixture#你可以通过它来启动浏览器(如Chromium、Firefox、WebKit等)#headless=False表示以有头模式运行浏览器,这样你可以看到浏览器界面#如果你想要以无头模式运行(即不显示浏览器界面),可以将headless设置为True或省略该参数(因为默认就是无头模式)1234567891011121314151617181920212223242526272829308.移动端浏览器支持移动端支持Safari浏览器、谷歌、不支持火狐,可以传入的设备有iPhone和Pixel2(Pixel2是谷歌的一款安卓手机)示例:模拟打开iPhone12ProMax上的Safari浏览器,然后手动设置定位,并打开百度地图并截图故宫的经纬度是39.913904,116.39014,我们可以通过geolocation参数传递给Webkit浏览器并初始化fromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:iphone_12_pro_max=p.devices['iPhone12ProMax']browser=p.webkit.launch(headless=False)context=browser.new_context(**iphone_12_pro_max,locale='zh-CN',geolocation={'longitude':116.39014,'latitude':39.913904},permissions=['geolocation'])page=context.new_page()page.goto('https://amap.com')page.wait_for_load_state(state='networkidle')page.screenshot(path='location-iphone.png')browser.close()123456789101112131415161718注意事项设置user-agent时,请确保它符合你的测试需求或目标网站的兼容性要求。如果你需要频繁地更改user-agent,考虑将设置user-agent的逻辑封装成一个函数或方法,以便在需要时重复使用。请注意,某些网站可能会根据user-agent的不同而返回不同的内容或执行不同的逻辑。因此,在自动化测试或爬虫开发过程中,合理地设置user-agent是非常重要的。额外信息–除了user-agent之外,Playwright还允许你在创建浏览器上下文时设置其他许多浏览器级别的参数,如窗口大小(viewport)、地理位置(geolocation)、语言(locale)、时区(timezone)等。这些参数可以帮助你更精确地模拟不同用户的浏览器环境,从而提高自动化测试或爬虫开发的效率和准确性。八.playwright如何绕过反爬虫检测检测地址:https://intoli.com/blog/not-possible-to-block-chrome-headless/chrome-headless-test.html网站为了保护信息不被爬取会添加一些反爬虫策略,比如直接打开谷歌浏览器,在控制台输入window.navigator.webdriver,可以看到该属性为false用selenium或者playWright打开浏览器,该属性为true网站很容易在前端根据这些属性判断是否使用了playwright,从而阻止用户采用自动化工具获取信息那么如何屏蔽掉这些属性,让网站无法识别是否使用了playwright呢?。首先通过浏览器打开网站https://bot.sannysoft.com/,该网站列出了常用的一些反爬虫检测属性使用playwright打开这个网站,发现webdriver属性被检测出异常fromplaywright.sync_apiimportsync_playwrightimporttimewithsync_playwright()aplaywright:browser_playwright.chromium.launch(headless=False)page=browser.new_page()page.goto('https://bot.sannysoft.com/')time.sleep(100)browser.close()123456789101112131防止webdriver属性被检测fromplaywright.sync_apiimportsync_playwrightimporttimewithsync_playwright()asplaywright:browser=playwright.chromium.launch(headless=False)page=browser.new_page()js="""Object.defineProperties(navigator,{webdriver:{get)=>false}});"""page.add_init_script(js)page.goto('https://bot.sannysoft.com/')time.sleep(1000)browser.close()123456789101112131415161718运行后可以看到webdriver还是没有通过,打开控制台,输入navigator.webdriver发现这个值的确为false,那么没有通过的原因是什么?找到网站检测的源码,有这么一几行代码//WebdriverTestconstwebdriverElement=document.getElementById('webdriver-result');if(navigator.webdriver||_.has(navigator,"webdriver")){webdriverElement.classList.add('failed');webdriverElement.classList.remove('passed');webdriverElement.innerHTML='present(failed)';}else{webdriverElement.classList.add('passed');webdriverElement.classList.remove('failed');webdriverElement.innerHTML='missing(passed)';}1234567891011属性_.has(navigator,“webdriver”)为true没有通过,这个表示navigator中有webdriver这个属性了,必须去掉才可以过这个检测。这个去掉该属性直接用GitHub上下载的一个stealth.min.js,地址为https://github.com/kingname/stealth.min.js/blob/main/stealth.min.jsfromplaywright.sync_apiimportsync_playwrightimporttimewithsync_playwright()asp:'''防止被浏览器检测的处理方法'''browser=p.chromium.launch(headless=False)page=browser.new_page() #加载stealth.min.js的javascriptwithopen('stealth.min.js','r')asf:js=f.read()page.add_init_script(js)page.goto('https://bot.sannysoft.com/')time.sleep(1000)browser.close()1234567891011121314151617181920运行后,这次检测已经通过了。2headless=True无头浏览器如何绕过反爬虫上面可以过检测用的是带界面浏览,当为无头浏览器是怎么样的呢,这里采用运行后进行截图的方式进行调试fromplaywright.sync_apiimportsync_playwrightimporttimewithsync_playwright()asp:browser=p.chromium.launch(headless=True)page=browser.new_page()withopen('stealth.min.js','r')asf:js=f.read()page.add_init_script(js)page.goto('https://bot.sannysoft.com/')#进行截图page.screenshot(path='bot_sannysoft.png',full_page=True)time.sleep(1000)browser.close()1234567891011121314151617181920当用无头浏览器时useragent没有通过,因此需重新设置useragentfromplaywright.sync_apiimportsync_playwrightimporttimewithsync_playwright()asp:browser=p.chromium.launch(headless=True,args=['--disable-blink-features=AutomationControlled','--user-agent=Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/120.0.0.0Safari/537.36'])page=browser.new_page()withopen('stealth.min.js','r')asf:js=f.read()page.add_init_script(js)#设置网页大小也可以防止无头浏览器被检测page.set_viewport_size({'width':1024,'height':768})page.goto('https://bot.sannysoft.com/')#进行截图page.screenshot(path='bot_sannysoft.png',full_page=True)time.sleep(1000)browser.close()1234567891011121314151617181920212223运行后,发现无头浏览器所有检测也均能通过。3.stealth.min.js作用‌stealth.min.js这个JavaScript主要用于保护用户隐私和匿名性,同时也在自动化测试中隐藏自动化特征。主要功能和应用场景:隐藏行为:可以通过模拟用户行为的方式来执行各种操作,比如点击、滚动、输入等,从而隐藏真实用户的操作轨迹使得网站无法准确追踪用户的行为。保护用户隐私和匿名性:通过修改‌UserAgent、禁用浏览器指纹识别、隐藏浏览器插件信息、阻止第三方Cookie等方式,stealth.min.js可以帮助用户在使用网络时保持匿名,防止被网站或第三方服务追踪个人信息。‌防止爬虫检测:在自动化测试中,如使用‌Selenium进行网页测试时,stealth.min.js可以帮助隐藏自动化工具的特征,防止被网站识别为非法访问,从而提高测试的效率和准确性。‌4.防止爬虫检测的方式使用无头浏览器:无头浏览器不会显示图形界面,从而降低了被检测的风险。设置User-Agent:通过模拟常见的浏览器User-Agent,可以减少被检测的可能性。添加随机延迟:在爬虫中添加随机延迟,模拟真实用户的操作习惯,降低被检测的风险。使用代理IP:通过代理IP来隐藏真实的IP地址,降低被识别和封锁的风险。九.通过CDP(ChromeDevToolsProtocol)连接现有浏览器1.CDP(ChromeDevToolsProtocol)和WDP(WebDriverProtocol)协议WDP和CDP是用于自动化浏览器的2个主要协议,大多数的浏览器自动化工具都是这两个协议实现和浏览器交互,通过代码来控制浏览器,完成浏览器的自动化行为(包括网页加载,点击、输入、按键、截图,导出pdf等)。2.WebDriverProtocolWebDriver是一个用于控制浏览器的远程控制接口,由SeleniumHQ开发,后来由W3C标准化。它提供了一个平台和语言中立的接口,支持几乎所有主流浏览器,如Chrome、Firefox、Safari、Edge、Opera等。官网:https://w3c.github.io/webdriver/它和浏览器的通信是通过JSONWire协议完成的,提供了RESTful的web服务,该服务端就被被称为webdriver,例如chromeDriver、geckoDriver等。webdriver的客户端可为任何语言,由webdriver客户端和webdriver服务端交互,webdriver服务端和浏览器交互,从而操作浏览器常见的客户端就是selenium,nightwatch,webdriverio加上我们的自己写的自动化测试代码之后,交互流程如下:常见的调用流程如下webdriver客户端(Python代码)通过调用自动化库API自动化库通过对应的webdriver服务端(如selenium)基于WDP协议通过JSONWire协议RESTful方式向浏览器发起操作请求(打开/关闭/点击/输入/按键/截图等等)浏览器接收到自动化工具请求后,完成相关操作然后返回响应给webdriver服务端webdriver服务器端接收到浏览器响应,返回响应给webdriver客户端3.ChromeDevToolsProtocolChromeDevToolsProtocol(CDP)是一个基于Chromium的浏览器的调试协议,如Chrome、Edge、Opera等。通过它可以直接和浏览器交互。控制浏览器的行为。官网:https://chromedevtools.github.io/devtools-protocol/浏览器是由客户端使用CDP协议直接控制的,客户端和浏览器之间没有类似于WebDriverProtocol的服务端(webdriver),客户端通过WebSocket直接和浏览器连接,由客户端通过WebSocket发送命令给浏览器,浏览器执行并返回响应。常见的客户端就是:Puppeteer和Playwright。它们不依赖于webdriver,而是通过ChromeDevToolsProtocol(CDP)直接与浏览器通话。从而更加灵活稳定的控制浏览器。4.WebDriverProtocol和ChromeDevToolsProtocol对比5.通过CDP控制本地原生谷歌浏览器fromplaywright.sync_apiimportsync_playwrightimportsubprocess"""1、打开浏览器,指定调试端口在CMD终端中通过命令行启动Chrome浏览器cdC:\ProgramFiles\Google\Chrome\Application&chrome.exe--remote-debugging-port=9222--user-data-dir=“C:/playwright/user_data”复制地址C:\ProgramFiles\Google\Chrome\Application添加到环境变量Path下chrome.exe--remote-debugging-port=12345--user-data-dir="D:\playwright_chrome"参数配置在启动浏览器的时候,我们还可以带上一些其它参数--incognito隐私模式打开-–start-maximized:窗口最大化--new-window:直接打开网址--remote-debugging-port是指定浏览器调试端口号,只要没被占用就行--user-data-dir指定运行浏览器的运行数据(用户配置文件目录),新建一个干净目录,不影响系统原来的数据(不存在会新建),如果不显式指定该参数,运行会污染浏览器默认的配置文件"""#1.打开浏览器,指定调试端口这个路径可以是Google浏览器的exe路径,也可以是快捷方式的路径#使用connect_over_cdp()方法接管前面已经打开的浏览器,获取到context上下文,通过上下文再获取到page对象chrome_path=r'"C:\Users\87772\AppData\Local\Google\Chrome\Application\chrome.exe"'debugging_port="--remote-debugging-port=9999"command=f"{chrome_path}{debugging_port}"subprocess.Popen(command,shell=True)#2.拦截请求defintercept_xhr(route,request):route.continue_()response=route.fetch()json=response.json()print(json)withsync_playwright()asp:#2.连接到已经通过CDP启动的浏览器实例。browser=p.chromium.connect_over_cdp("http://localhost:9999")content=browser.contexts[0]page=content.new_page()#设置拦截规则page.route("**/api/sns/web/v1/homefeed",lambdaroute,request:intercept_xhr(route,request))page.goto('https://www.xiaohongshu.com/')page.wait_for_selector('.feeds-container')#点击关闭page.locator(".close-button").click()#获取页面内容高度page_height=page.evaluate('()=>document.body.scrollHeight')#模拟鼠标滚动操作,向下滚动到底部whilepage.evaluate('()=>window.scrollY+window.innerHeight')
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-7 07:12 , Processed in 0.578277 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表