【爬虫】PlayWright使用说明

持续更新中

1. 安装

安装参考:安装

支持pip和conda安装,以conda为例:

shell 复制代码
conda config --add channels conda-forge
conda config --add channels microsoft
conda install pytest-playwright
playwright install

如遇到防火墙或者公司网络限制,可参考我另一篇文字conda的proxy设置方式:[]

如果是laywright install的时候需要proxy,则:

shell 复制代码
set HTTP_PROXY=你的proxy地址
set HTTPS_PROXY=你的proxy地址
playwright install

2. 使用

2.1 事件

事件列表:

  • close: page 关闭
  • console:当页面中的 JavaScript 调用控制台 API 方法之一(例如console.logconsole.dir)时产生的事件。
    • 传递进console.log的参数可在ConsoleMessage事件处理程序参数中使用。,ConsoleMessage对象由页面通过page.on("console")事件分派。
    • 对于页面中记录的每条ConsoleMessage,Playwright 上下文中都会有相应的事件。
  • crash:page崩溃。
    • 如果浏览器page尝试分配过多内存,则可能会崩溃。当page崩溃时,正在进行的操作和后续操作将抛出。
  • dialog: JavaScript 对话框出现事件,如alert, prompt, confirmbeforeunload
  • domcontentloaded:JavaScript的DOMContentLoaded事件被分发时的事件。
    • 当 HTML 文档已完全解析且所有延迟脚本(deferred scripts)(<script defer src="..."><script type="module">)已下载且执行完时,将触发DOMContentLoaded事件。它不会等待图像、子帧和异步脚本等其他内容完成加载。
    • DOMContentLoaded不等待样式表(stylesheets )加载,但延迟脚本(deferred scripts)会等待样式表(stylesheets ),并且DOMContentLoaded事件排在延迟脚本之后。此外,非延迟或异步的脚本(例如<script>)将等待已解析的样式表加载。
    • 应仅使用不同的事件load来检测页面是否已完全加载。使用load一个常见错误是用成了DOMContentLoaded,因为后者可能更合适。
    • 此事件不可取消。
  • download: 附件(attachment)开始下载的事件。
    • page.on("download")可分发Download对象,该对象可用于对下载文件的操作。
  • filechooser:当应该出现文件选择器( file chooser)时的事件,例如单击 <input type=file> 后。
  • frameattachedFrame对象被附加(attached)的事件。
    • Frame介绍: 通过使用Frame,你可以在同一个浏览器窗口中显示不止一个页面,简而言之,就是在一个窗口中显示多个页面。 每个页面称之为一个框架。并且每个框架独立于其他的框架。
    • Frame对象的生命周期受三个事件控制:page.on("frameattached") ,page.on("framenavigated") ,page.on("framedetached")
  • framedetached: Frame被分离( detached).
  • framenavigated:Frame被导航到新的 url。
  • load: JavaScript的load事件被分发时的事件.
    • load介绍:整个页面加载完成后会触发load事件,包括所有依赖资源(例如样式表、脚本、iframe 和图像,但延迟加载( loaded lazily)的资源除外)。这不同于DOMContentLoaded,后者在页面 DOM 加载完成后立即触发,而不等待资源完成加载。
  • pageerror:当页面内发生未捕获的异常时的事件。
  • popup:当页面打开新选项卡或窗口时的事件。
    • browser_context.on("page")也会触发此事件,但仅针对与此页面相关的弹出窗口(popups)。
    • 该页面最早可用的时刻是导航到初始 URL 时。例如,当使用 window.open('http://example.com') 打开弹出窗口时,当对http://example.com"的网络请求完成并且其响应已开始加载时,将触发此事件弹出窗口。
  • request:当页面发出请求时的事件。
    • request对象介绍:每当页面发送对网络资源的请求时,Page对象都会发出以下事件序列:page.on("request")page.on("response")page.on("requestfinished")
  • requestfailed:当请求失败时的事件,例如超时。
  • requestfinished:当响应正文下载且请求完成时的事件。
  • response:当/如果收到请求的响应状态和标头时的事件。
  • websocketWebSocket请求发出时的事件。
  • worker:当页面生成专用 WebWorker 时的事件。
    • Web Workers 可以在与 Web 应用程序的主执行线程分开的后台线程中运行脚本操作。这样做的优点是可以在单独的线程中执行繁重的处理,从而允许主(通常是 UI)线程运行而不会被阻塞/减慢。
  1. 处理crash,处理崩溃最常见的方式是捕获异常:
python 复制代码
try:
    # crash might happen during a click.
    page.click("button")
    # or while waiting for an event.
    page.wait_for_event("popup")
except Error as e:
    pass
    # when the page crashes, exception message contains "crash".

2.2 page.on() 监听事件

2.3 wait_util参数

wait_until : Union["commit", "domcontentloaded", "load", "networkidle", None]

等待到某个事件触发,默认值 load. 可选参数:

  • 'domcontentloaded' - DOMContentLoaded 事件触发
  • 'load' - load 事件触发.
  • 'networkidle' - 不建议使用 ,当网络断连至少 500 ms时触发。不要使用此方法进行测试,而是依靠网络assert来评估准备情况。
  • 'commit' - 当收到网络响应并且文档开始时加载中时触发。

2.4 Role:

"alert" | "alertdialog" | "application" | "article" | "banner" | "blockquote" | "button" | "caption" | "cell" | "checkbox" | "code" | "columnheader" | "combobox" | "complementary" | "contentinfo" | "definition" | "deletion" | "dialog" | "directory" | "document" | "emphasis" | "feed" | "figure" | "form" | "generic" | "grid" | "gridcell" | "group" | "heading" | "img" | "insertion" | "link" | "list" | "listbox" | "listitem" | "log" | "main" | "marquee" | "math" | "meter" | "menu" | "menubar" | "menuitem" | "menuitemcheckbox" | "menuitemradio" | "navigation" | "none" | "note" | "option" | "paragraph" | "presentation" | "progressbar" | "radio" | "radiogroup" | "region" | "row" | "rowgroup" | "rowheader" | "scrollbar" | "search" | "searchbox" | "separator" | "slider" | "spinbutton" | "status" | "strong" | "subscript" | "superscript" | "switch" | "tab" | "table" | "tablist" | "tabpanel" | "term" | "textbox" | "time" | "timer" | "toolbar" | "tooltip" | "tree" | "treegrid" | "treeitem"

三、 调试和定位元素

在编写自动化测试脚本时,经常需要调试和定位页面上的元素。Playwright提供了多种方法来定位元素,如使用CSS选择器、XPath等。

3.1 调试

使用page.pause():在脚本中添加page.pause()方法,可以在执行到该位置时暂停脚本,并自动打开Playwright Inspector工具,方便进行页面调试。

Playwright Inspector是Playwright框架中自带的GUI工具,可以辅助开发者调试Playwright脚本。以下是Playwright Inspector的使用方法:
【PlayWright】Playwright Inspector使用

3.2 定位元素 Locator

Playwright提供了page.locator()方法来定位页面上的元素,它支持多种选择器,如CSS选择器、XPath等。

Locator是用来执行动作的对象。以前的Page.click已经被废弃,用Locator.click.

除了推荐的Locator(如 page.get_by_role()page.get_by_text())之外,Playwright 还支持本各种其他定位器。

chrom中便捷获取xpath的方法

Locator获取元素属性:

html 复制代码
<a data-v-323b850e="" class="titlecontent" href="https://xxxxxxx" target="_blank" title="硬件单板互连设计工程师" style="max-width: 598px;"><!---->
	<span data-v-323b850e="">硬件单板互连设计工程师</span>
</a>
python 复制代码
h1 = i.locator('a.titlecontent')
url = h1.get_attribute('href') # https://xxxxxxx
title = h1.get_attribute('title') # 硬件单板互连设计工程师

3.2.1 CSS locator

3.2.2 N-th element locator

3.2.3 Parent element locator

3.2.4 Parent element locator

3.2.5 Vue locator

3.2.6 XPath locator

3.2.7 Label to form control retargeting

3.2.8 Legacy text locator

3.2.9 id, data-testid, data-test-id, data-test selectors

3.2.10 Chaining selectors

3.2.11 Intermediate matches

3.3 定位元素 ElementHandle

The difference between the Locator and ElementHandle is that the ElementHandle points to a particular element, while Locator captures the logic of how to retrieve an element.

ElementHandle 也可以用get_attribute获取元素属性。

Locator转ElementHandle

Locator有以下两个函数,可用来将返回Locator对应的ElementHandle

python 复制代码
    def element_handle(
        self, *, timeout: typing.Optional[float] = None
    ) -> "ElementHandle":
        """Locator.element_handle

        Resolves given locator to the first matching DOM element. If there are no matching elements, waits for one. If
        multiple elements match the locator, throws.

        Parameters
        ----------
        timeout : Union[float, None]
            Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can
            be changed by using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.

        Returns
        -------
        ElementHandle
        """

        return mapping.from_impl(
            self._sync(self._impl_obj.element_handle(timeout=timeout))
        )

    def element_handles(self) -> typing.List["ElementHandle"]:
        """Locator.element_handles

        Resolves given locator to all matching DOM elements. If there are no matching elements, returns an empty list.

        Returns
        -------
        List[ElementHandle]
        """

        return mapping.from_impl_list(self._sync(self._impl_obj.element_handles()))

参考

官网教程
官方视频

相关推荐
聪明的墨菲特i1 小时前
Python爬虫学习
爬虫·python·学习
oliveira-time3 小时前
爬虫学习6
爬虫
xiaoxiongip6668 小时前
HTTP 和 HTTPS
网络·爬虫·网络协议·tcp/ip·http·https·ip
兆。10 小时前
掌握 PyQt5:从零开始的桌面应用开发
开发语言·爬虫·python·qt
API快乐传递者16 小时前
淘宝反爬虫机制的主要手段有哪些?
爬虫·python
兜里有糖请分享1 天前
Python中序列化/反序列化JSON格式的数据
爬虫·python
亿牛云爬虫专家1 天前
用Puppeteer点击与数据爬取:实现动态网页交互
javascript·爬虫·爬虫代理·puppeteer·数据·代理ip·16yun
API快乐传递者1 天前
利用Python 的爬虫技术淘宝天猫销量和库存
开发语言·爬虫·python
操练起来1 天前
【Python实战案例】爬虫项目实例(附赠源码)
数据库·爬虫·python
编码小袁2 天前
利用爬虫爬取网站信息
爬虫