Skip to main content

BrowserContext

BrowserContext 提供了一种操作多个独立浏览器会话的方法。

如果页面打开另一个页面,例如使用 window.open 调用,则弹出窗口将属于父页面的浏览器上下文。

Playwright 允许使用 browser.new_context(**kwargs) 方法创建“隐身”浏览器上下文。“隐身”浏览器上下文不会将任何浏览数据写入磁盘。

# 创建一个新的隐身浏览器上下文
context = browser.new_context()
# 在上下文中创建一个新页面。
page = context.new_page()
page.goto("https://example.com")
# 一旦不再需要上下文,就将其丢弃。
context.close()

browser_context.on("backgroundpage")

Added in: v1.11
note

仅适用于 Chromium 浏览器的持久上下文。

当在上下文中创建新的后台页面时触发。

background_page = context.wait_for_event("backgroundpage")

browser_context.on("close")

Added in: v1.8

当浏览器上下文关闭时触发。这可能是由以下原因之一引起的:

  • 浏览器上下文已关闭。
  • 浏览器应用程序已关闭或崩溃。
  • browser.close() 方法被调用。

browser_context.on("page")

Added in: v1.8

当在 BrowserContext 中创建新页面时触发此事件。页面可能仍在加载中。该事件也会针对弹出页面触发。另请参阅 page.on("popup") 以接收与特定页面相关的弹出窗口事件。

页面可用的最早时刻是它导航到初始 url 时。例如,当使用 window.open('http://example.com') 打开弹出窗口时,当对 "http://example.com" 的网络请求完成并且其响应已开始在弹出窗口中加载时,将触发此事件。

with context.expect_page() as page_info:
page.locator("a[target=_blank]").click(),
page = page_info.value
print(page.evaluate("location.href"))
note

使用 page.wait_for_load_state(**kwargs) 等待页面达到特定状态(在大多数情况下您不需要它)。

browser_context.on("request")

Added in: v1.12

当通过此上下文创建的任何页面发出请求时触发。request 对象是只读的。要仅监听来自特定页面的请求,请使用 page.on("request")

为了拦截和改变请求,请参阅 browser_context.route(url, handler, **kwargs)page.route(url, handler, **kwargs)

browser_context.on("requestfailed")

Added in: v1.12

当请求失败(例如超时)时触发。要仅监听来自特定页面的失败请求,请使用 page.on("requestfailed")

note

HTTP 错误响应(如 404 或 503)从 HTTP 的角度来看仍然是成功的响应,因此请求将以 browser_context.on("requestfinished") 事件完成,而不是 browser_context.on("requestfailed")

browser_context.on("requestfinished")

Added in: v1.12

当请求在下载响应体后成功完成时触发。对于成功的响应,事件序列为 requestresponserequestfinished。要监听来自特定页面的成功请求,请使用 page.on("requestfinished")

browser_context.on("response")

Added in: v1.12

当收到请求的 response 状态和标头时触发。对于成功的响应,事件序列为 requestresponserequestfinished。要监听来自特定页面的响应事件,请使用 page.on("response")

browser_context.on("serviceworker")

Added in: v1.11
note

Service Worker 仅在基于 Chromium 的浏览器上受支持。

当在上下文中创建新的 Service Worker 时触发。

browser_context.add_cookies(cookies)

Added in: v1.8
  • cookies <List[Dict]>#
    • name <str>
    • value <str>
    • url <str> 需要 url 或 domain / path。可选。
    • domain <str> 需要 url 或 domain / path。可选。
    • path <str> 需要 url 或 domain / path。可选。
    • expires <float> 以秒为单位的 Unix 时间。可选。
    • httpOnly <bool> 可选。
    • secure <bool> 可选。
    • sameSite <"Strict"|"Lax"|"None"> 可选。
  • 返回值: <NoneType>#

将 cookie 添加到此浏览器上下文中。此上下文中的所有页面都将安装这些 cookie。可以通过 browser_context.cookies(**kwargs) 获取 cookie。

browser_context.add_cookies([cookie_object1, cookie_object2])

browser_context.add_init_script(**kwargs)

Added in: v1.8
  • path <Union[str, pathlib.Path]> JavaScript 文件的路径。如果 path 是相对路径,则相对于当前工作目录解析。可选。#
  • script <str> 要在浏览器上下文的所有页面中评估的脚本。可选。#
  • 返回值: <NoneType>#

添加一个脚本,该脚本将在以下情况之一中进行评估:

  • 每当在浏览器上下文中创建页面或导航时。
  • 每当在浏览器上下文的任何页面中附加或导航子框架时。在这种情况下,脚本将在新附加框架的上下文中进行评估。

脚本在创建文档之后但在运行任何脚本之前进行评估。这对于修改 JavaScript 环境(例如为 Math.random 设定种子)很有用。

页面加载前覆盖 Math.random 的示例:

// preload.js
Math.random = () => 42;
# 在您的 playwright 脚本中,假设 preload.js 文件位于同一目录中。
browser_context.add_init_script(path="preload.js")
note

通过 browser_context.add_init_script(**kwargs)page.add_init_script(**kwargs) 安装的多个脚本的评估顺序未定义。

browser_context.background_pages

Added in: v1.11
note

后台页面仅在基于 Chromium 的浏览器上受支持。

上下文中所有现有的后台页面。

browser_context.browser

Added in: v1.8

返回上下文的浏览器实例。如果它是作为持久上下文启动的,则返回 null。

browser_context.clear_cookies()

Added in: v1.8

清除上下文 cookie。

browser_context.clear_permissions()

Added in: v1.8

清除浏览器上下文的所有权限覆盖。

context = browser.new_context()
context.grant_permissions(["clipboard-read"])
# 执行操作 ..
context.clear_permissions()

browser_context.close()

Added in: v1.8

关闭浏览器上下文。属于浏览器上下文的所有页面都将被关闭。

note

无法关闭默认浏览器上下文。

browser_context.cookies(**kwargs)

Added in: v1.8

如果未指定 URL,则此方法返回所有 cookie。如果指定了 URL,则仅返回影响这些 URL 的 cookie。

browser_context.expect_event(event, **kwargs)

Added in: v1.8

等待事件触发并将其值传递给谓词函数。当谓词返回真值时返回。如果上下文在事件触发之前关闭,将抛出错误。返回事件数据值。

with context.expect_event("page") as event_info:
page.get_by_role("button").click()
page = event_info.value

browser_context.expect_page(**kwargs)

Added in: v1.9

执行操作并等待在上下文中创建新的 Page。如果提供了谓词,则将 Page 值传递给 predicate 函数并等待 predicate(event) 返回真值。如果在创建新 Page 之前上下文关闭,将抛出错误。

browser_context.expose_binding(name, callback, **kwargs)

Added in: v1.8
  • name <str> window 对象上的函数名称。#
  • callback <Callable> 将在 Playwright 上下文中调用的回调函数。#
  • handle <bool> 是否作为句柄传递参数,而不是按值传递。传递句柄时,仅支持一个参数。按值传递时,支持多个参数。#
  • 返回值: <NoneType>#

该方法在上下文中每个页面的每个框架的 window 对象上添加一个名为 name 的函数。当被调用时,该函数执行 callback 并返回一个解析为 callback 返回值的 Promise。如果 callback 返回 Promise,它将被等待。

callback 函数的第一个参数包含有关调用者的信息:{ browserContext: BrowserContext, page: Page, frame: Frame }

有关仅页面版本,请参阅 page.expose_binding(name, callback, **kwargs)

将页面 URL 暴露给上下文中所有页面中的所有框架的示例:

from playwright.sync_api import sync_playwright

def run(playwright):
webkit = playwright.webkit
browser = webkit.launch(headless=false)
context = browser.new_context()
context.expose_binding("pageURL", lambda source: source["page"].url)
page = context.new_page()
page.set_content("""
<script>
async function onClick() {
document.querySelector('div').textContent = await window.pageURL();
}
</script>
<button onclick="onClick()">Click me</button>
<div></div>
""")
page.get_by_role("button").click()

with sync_playwright() as playwright:
run(playwright)

传递元素句柄的示例:

def print(source, element):
print(element.text_content())

context.expose_binding("clicked", print, handle=true)
page.set_content("""
<script>
document.addEventListener('click', event => window.clicked(event.target));
</script>
<div>Click me</div>
<div>Or click me</div>
""")

browser_context.expose_function(name, callback)

Added in: v1.8
  • name <str> window 对象上的函数名称。#
  • callback <Callable> 将在 Playwright 上下文中调用的回调函数。#
  • 返回值: <NoneType>#

该方法在上下文中每个页面的每个框架的 window 对象上添加一个名为 name 的函数。当被调用时,该函数执行 callback 并返回一个解析为 callback 返回值的 Promise

如果 callback 返回 Promise,它将被等待。

有关仅页面版本,请参阅 page.expose_function(name, callback)

向上下文中的所有页面添加 sha256 函数的示例:

import hashlib
from playwright.sync_api import sync_playwright

def sha256(text):
m = hashlib.sha256()
m.update(bytes(text, "utf8"))
return m.hexdigest()


def run(playwright):
webkit = playwright.webkit
browser = webkit.launch(headless=False)
context = browser.new_context()
context.expose_function("sha256", sha256)
page = context.new_page()
page.set_content("""
<script>
async function onClick() {
document.querySelector('div').textContent = await window.sha256('PLAYWRIGHT');
}
</script>
<button onclick="onClick()">Click me</button>
<div></div>
""")
page.get_by_role("button").click()

with sync_playwright() as playwright:
run(playwright)

browser_context.grant_permissions(permissions, **kwargs)

Added in: v1.8
  • permissions <List[str]> 要授予的权限或权限数组。权限可以是以下值之一:#
    • 'geolocation'
    • 'midi'
    • 'midi-sysex' (system-exclusive midi)
    • 'notifications'
    • 'camera'
    • 'microphone'
    • 'background-sync'
    • 'ambient-light-sensor'
    • 'accelerometer'
    • 'gyroscope'
    • 'magnetometer'
    • 'accessibility-events'
    • 'clipboard-read'
    • 'clipboard-write'
    • 'payment-handler'
  • origin <str> 将被授予权限的 origin,例如 "https://example.com"。#
  • 返回值: <NoneType>#

向浏览器上下文授予指定权限。如果指定了 origin,则仅向该 origin 授予相应的权限。

browser_context.new_cdp_session(page)

Added in: v1.11
  • page <Page|Frame> 为其创建新会话的目标。为了向后兼容,此参数名为 page,但它可以是 PageFrame 类型。#
  • 返回值: <CDPSession>#
note

CDP 会话仅在基于 Chromium 的浏览器上受支持。

返回新创建的会话。

browser_context.new_page()

Added in: v1.8

在浏览器上下文中创建一个新页面。

browser_context.pages

Added in: v1.8

返回上下文中所有打开的页面。

browser_context.route(url, handler, **kwargs)

Added in: v1.8
  • url <str|Pattern|Callable[URL]:bool> 路由时要匹配的 glob 模式、正则表达式模式或接收 URL 的谓词。当通过上下文选项提供了 base_url 并且传递的 URL 是路径时,它将通过 new URL() 构造函数进行合并。#
  • handler <Callable[Route, Request]> 路由请求的处理程序函数。#
  • times <int> 路由应使用的频率。默认情况下,每次都会使用。Added in: v1.15#
  • 返回值: <NoneType>#

路由提供了修改浏览器上下文中任何页面发出的网络请求的功能。一旦启用路由,每个匹配 url 模式的请求都将暂停,除非它被继续、满足或中止。

note

browser_context.route(url, handler, **kwargs) 不会拦截被 Service Worker 拦截的请求。请参阅问题。我们建议在使用请求拦截时通过将 browser.new_context.service_workers 设置为 'block' 来禁用 Service Worker。

中止所有图片请求的简单处理程序示例:

context = browser.new_context()
page = context.new_page()
context.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
page.goto("https://example.com")
browser.close()

或者使用正则表达式模式的相同代码段:

context = browser.new_context()
page = context.new_page()
context.route(re.compile(r"(\.png$)|(\.jpg$)"), lambda route: route.abort())
page = await context.new_page()
page = context.new_page()
page.goto("https://example.com")
browser.close()

可以检查请求以决定路由操作。例如,模拟包含某些 post data 的所有请求,并保持所有其他请求不变:

def handle_route(route):
if ("my-string" in route.request.post_data)
route.fulfill(body="mocked-data")
else
route.continue_()
context.route("/api/**", handle_route)

当请求同时匹配两个处理程序时,页面路由(使用 page.route(url, handler, **kwargs) 设置)优先于浏览器上下文路由。

要删除带有处理程序的路由,可以使用 browser_context.unroute(url, **kwargs)

note

启用路由会禁用 http缓存。

browser_context.route_from_har(har, **kwargs)

Added in: v1.23
  • har <Union[str, pathlib.Path]> 带有预制网络数据的 HAR 文件路径。如果 path 是相对路径,则相对于当前工作目录解析。#

  • not_found <"abort"|"fallback"> 如果设置为 'abort',则 HAR 文件中未找到的任何请求都将被中止。#

    • 如果设置为 'fallback',则会传递给处理程序链中的下一个路由处理程序。

    默认为 abort。

  • update <bool> 如果指定,则使用实际网络信息更新给定的 HAR,而不是从文件提供服务。#

  • url <str|Pattern> 用于匹配请求 URL 的 glob 模式、正则表达式或谓词。仅具有与模式匹配的 URL 的请求将由 HAR 文件提供服务。如果未指定,则所有请求都将由 HAR 文件提供服务。#

  • 返回值: <NoneType>#

如果指定,则在上下文中发出的网络请求将由 HAR 文件提供服务。阅读有关 从 HAR 重播 的更多信息。

Playwright 不会从 HAR 文件提供被 Service Worker 拦截的请求。请参阅问题。我们建议在使用请求拦截时通过将 browser.new_context.service_workers 设置为 'block' 来禁用 Service Worker。

browser_context.service_workers

Added in: v1.11
note

Service Worker 仅在基于 Chromium 的浏览器上受支持。

上下文中所有现有的 Service Worker。

browser_context.set_default_navigation_timeout(timeout)

Added in: v1.8

此设置将更改以下方法和相关快捷方式的默认最大导航时间:

browser_context.set_default_timeout(timeout)

Added in: v1.8

此设置将更改所有接受 timeout 选项的方法的默认最长时间。

browser_context.set_extra_http_headers(headers)

Added in: v1.8
  • headers <Dict[str, str]> 包含随每个请求发送的附加 HTTP 标头的对象。所有标头值必须是字符串。#
  • 返回值: <NoneType>#

额外的 HTTP 标头将随上下文中任何页面发起的每个请求一起发送。这些标头与使用 page.set_extra_http_headers(headers) 设置的特定于页面的额外 HTTP 标头合并。如果页面覆盖了特定标头,则将使用特定于页面的标头值代替浏览器上下文标头值。

note

browser_context.set_extra_http_headers(headers) 不保证传出请求中标头的顺序。

browser_context.set_geolocation(geolocation)

Added in: v1.8
  • geolocation <NoneType|Dict>#
    • latitude <float> Latitude between -90 and 90.
    • longitude <float> Longitude between -180 and 180.
    • accuracy <float> Non-negative accuracy value. Defaults to 0.
  • 返回值: <NoneType>#

设置上下文的地理位置。传递 nullundefined 模拟位置不可用。

browser_context.set_geolocation({"latitude": 59.95, "longitude": 30.31667})
note

考虑使用 browser_context.grant_permissions(permissions, **kwargs) 授予浏览器上下文页面读取其地理位置的权限。

browser_context.set_offline(offline)

Added in: v1.8
  • offline <bool> 是否为浏览器上下文模拟网络离线。#
  • 返回值: <NoneType>#

browser_context.storage_state(**kwargs)

Added in: v1.8
  • path <Union[str, pathlib.Path]> 保存存储状态的文件路径。如果 path 是相对路径,则相对于当前工作目录解析。如果未提供路径,则仍返回存储状态,但不会保存到磁盘。#
  • 返回值: <Dict>#

返回此浏览器上下文的存储状态,包含当前 cookie 和本地存储快照。

browser_context.unroute(url, **kwargs)

Added in: v1.8

删除使用 browser_context.route(url, handler, **kwargs) 创建的路由。未指定 handler 时,删除 url 的所有路由。

browser_context.wait_for_event(event, **kwargs)

Added in: v1.8
  • event <str> 事件名称,通常与传递给 *.on(event) 的名称相同。#
  • predicate <Callable> 接收事件数据并在等待应解析时解析为真值。#
  • timeout <float> 等待的最长时间(以毫秒为单位)。默认为 30000(30 秒)。传递 0 可禁用超时。可以使用 browser_context.set_default_timeout(timeout) 更改默认值。#
  • 返回值: <Any>#
note

在大多数情况下,您应该使用 browser_context.expect_event(event, **kwargs)

等待给定的 event 触发。如果提供了谓词,则将事件的值传递给 predicate 函数并等待 predicate(event) 返回真值。如果浏览器上下文在 event 触发之前关闭,将抛出错误。

browser_context.request

Added in: v1.16

与其上下文关联的 API 测试助手。使用此 API 发出的请求将使用上下文 cookie。

browser_context.tracing

Added in: v1.12