Playwright for Python:Request 类(含 request.all_headers())中文版文档
Request 类对应浏览器页面发起的单个网络请求,可用于获取请求的 URL、方法、头信息、参数等详情,也可配合路由(Route)实现请求拦截、修改或中止。request.all_headers() 是 Request 类的核心方法,用于获取该请求的所有 HTTP 头信息(包含默认头和自定义头)。
快速示例
同步示例(捕获并打印请求所有头信息)
from playwright.sync_api import sync_playwright, Playwright
def run(playwright: Playwright):
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
# 监听页面所有请求,获取并打印请求头
def handle_request(request):
# 排除无关请求(如图片、样式),仅关注文档请求
if request.resource_type == "document":
print("=" * 50)
print(f"请求URL:{request.url}")
print(f"请求方法:{request.method}")
print("所有请求头:")
# 获取并遍历所有请求头
all_headers = request.all_headers()
for header_name, header_value in all_headers.items():
print(f" {header_name}: {header_value}")
print("=" * 50)
page.on("request", handle_request)
page.goto("https://example.com")
browser.close()
with sync_playwright() as playwright:
run(playwright)
异步示例(筛选指定请求头信息)
import asyncio
from playwright.async_api import async_playwright, Playwright
async def run(playwright: Playwright):
browser = await playwright.chromium.launch()
context = await browser.new_context()
page = await context.new_page()
# 异步监听请求,提取Authorization和User-Agent头
async def handle_request(request):
if "api.example.com" in request.url:
all_headers = await request.all_headers()
# 获取指定头信息(兼容头不存在的情况)
auth_header = all_headers.get("Authorization", "未设置")
user_agent = all_headers.get("User-Agent", "未设置")
print(f"API请求认证头:{auth_header}")
print(f"API请求用户代理:{user_agent}")
page.on("request", handle_request)
await page.goto("https://example.com")
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
Request 类核心属性
| 属性 | 用途 | 返回类型 | 说明 |
|---|---|---|---|
url | 获取请求的完整 URL(含协议、域名、路径、参数) | str | 只读,如 https://example.com/path?key=value |
method | 获取请求的 HTTP 方法 | str | 只读,如 GET、POST、PUT、DELETE |
resource_type | 获取请求的资源类型 | str | 只读,常见值:document(网页文档)、xhr(异步请求)、fetch(Fetch 请求)、image(图片)、script(脚本)等 |
post_data | 获取 POST 请求的提交数据(原始格式) | Optional[str/bytes] | 只读,GET 请求返回 None |
post_data_json | 获取 POST 请求的 JSON 格式提交数据 | Optional[dict] | 只读,非 JSON 格式返回 None |
headers | 获取请求的公共头信息(简化版,不含浏览器内部头) | Dict[str, str] | 只读,与 all_headers() 对比见下文 |
is_navigation_request | 判断该请求是否为页面导航请求 | bool | 只读,True 表示是页面跳转的主请求 |
frame | 获取发起该请求的页面框架 | Optional[Frame] | 只读,部分请求(如全局请求)可能返回 None |
context | 获取请求所属的浏览器上下文 | BrowserContext | 只读 |
Request 类核心方法
1. all_headers(核心方法)
功能描述
获取当前请求的所有 HTTP 头信息,包括浏览器自动添加的内部头(如 Sec-Fetch-Site、Sec-Ch-Ua)、自定义头(如 Authorization)以及默认头(如 User-Agent、Accept),返回完整的头信息字典。
用法示例
# 同步
def handle_request(request):
all_headers = request.all_headers()
# 打印所有头信息
print("完整请求头:", all_headers)
# 获取单个头(忽略大小写,字典键已标准化)
accept_header = all_headers.get("Accept")
print(f"Accept头:{accept_header}")
# 异步
async def handle_request(request):
all_headers = await request.all_headers()
sec_ua_header = all_headers.get("Sec-Ch-Ua")
print(f"浏览器UA信息头:{sec_ua_header}")
返回值
Dict[str, str]:键为头字段名称(标准化为小写或驼峰式,如 user-agent 或 User-Agent),值为头字段对应的值。
与 request.headers 的核心区别
| 特性 | request.all_headers() | request.headers |
|---|---|---|
| 包含头类型 | 所有头(公共头+浏览器内部头+自定义头) | 仅公共头(自定义头+核心默认头,不含内部头) |
| 完整性 | 完整,覆盖所有请求头 | 简化,仅展示常用头 |
| 适用场景 | 调试、完整请求分析、需要获取内部头信息 | 常规业务场景,获取自定义/常用头 |
| 示例返回 | 包含 Sec-Fetch-Mode、Sec-Ch-Ua-Platform 等 | 仅包含 User-Agent、Authorization、Accept 等 |
2. failure
功能描述
获取请求失败的原因(若请求成功则返回 None),用于排查网络请求失败问题(如超时、连接断开、4xx/5xx 响应不属于失败,仅网络层面异常才算失败)。
用法示例
# 同步
def handle_request_finished(request):
failure = request.failure()
if failure:
print(f"请求 {request.url} 失败:")
print(f" 失败原因:{failure['error']}")
print(f" 失败消息:{failure['message']}")
page.on("requestfinished", handle_request_finished)
# 异步
async def handle_request_finished(request):
failure = await request.failure()
if failure:
print(f"请求 {request.url} 失败:{failure['message']}")
page.on("requestfinished", handle_request_finished)
返回值
Optional[Dict[str, str]]:请求失败时返回包含 error(错误类型)和 message(错误详情)的字典;请求成功时返回 None。
3. header_value
功能描述
获取指定名称的请求头值,支持模糊匹配(忽略大小写),若头不存在则返回 None,适用于快速获取单个特定头信息。
用法示例
# 同步
def handle_request(request):
# 获取User-Agent头(忽略大小写)
user_agent = request.header_value("user-agent")
# 获取Authorization头
auth = request.header_value("Authorization")
print(f"User-Agent:{user_agent}")
print(f"Authorization:{auth or '无认证信息'}")
# 异步
async def handle_request(request):
accept = await request.header_value("Accept")
print(f"Accept头:{accept}")
参数
name:请求头名称(字符串,大小写不敏感,如 "user-agent"、"User-Agent" 效果一致)。
返回值
Optional[str]:指定头的值;若头不存在返回 None。
4. redirect_from
功能描述
获取当前请求的来源请求(即该请求是由哪个请求重定向而来),若无重定向则返回 None。
用法示例
# 同步
def handle_request(request):
redirect_source = request.redirect_from()
if redirect_source:
print(f"请求 {request.url} 来自重定向:{redirect_source.url}")
else:
print(f"请求 {request.url} 非重定向请求")
# 异步
async def handle_request(request):
redirect_source = await request.redirect_from()
if redirect_source:
print(f"重定向来源:{redirect_source.url}")
返回值
Optional[Request]:重定向来源的 Request 实例;无重定向时返回 None。
5. redirect_to
功能描述
获取当前请求重定向到的目标请求(即该请求将重定向到哪个 URL),若无重定向则返回 None。
用法示例
# 同步
def handle_request(request):
redirect_target = request.redirect_to()
if redirect_target:
print(f"请求 {request.url} 将重定向到:{redirect_target.url}")
# 异步
async def handle_request(request):
redirect_target = await request.redirect_to()
if redirect_target:
print(f"重定向目标:{redirect_target.url}")
返回值
Optional[Request]:重定向目标的 Request 实例;无重定向时返回 None。
6. response
功能描述
获取当前请求对应的响应(Response 实例),若请求尚未收到响应或响应失败则返回 None。
用法示例
# 同步
def handle_request_finished(request):
response = request.response()
if response:
print(f"请求 {request.url} 响应状态码:{response.status}")
print(f"响应状态文本:{response.status_text}")
page.on("requestfinished", handle_request_finished)
# 异步
async def handle_request_finished(request):
response = await request.response()
if response:
print(f"响应状态码:{response.status}")
返回值
Optional[Response]:请求对应的 Response 实例;无响应时返回 None。
常见场景实战
场景 1:拦截请求并验证自定义头是否存在
# 同步
def test_custom_header_exists(page):
# 拦截所有API请求
def handle_route(route, request):
all_headers = request.all_headers()
# 验证是否包含自定义测试头
assert "X-Test-Id" in all_headers, "请求缺少X-Test-Id自定义头"
assert all_headers["X-Test-Id"] == "playwright-test-123", "X-Test-Id头值不匹配"
# 继续执行请求
route.continue_()
page.route("**/api/**", handle_route)
page.goto("https://example.com")
# 异步
async def test_custom_header_exists(page):
async def handle_route(route, request):
all_headers = await request.all_headers()
assert "X-Test-Id" in all_headers
await route.continue_()
await page.route("**/api/**", handle_route)
await page.goto("https://example.com")
场景 2:筛选指定资源类型的请求头
# 同步
def filter_xhr_request_headers(page):
xhr_headers_list = []
def handle_request(request):
if request.resource_type == "xhr":
headers = request.all_headers()
xhr_headers_list.append({
"url": request.url,
"headers": headers
})
page.on("request", handle_request)
page.goto("https://example.com")
# 打印所有XHR请求的头信息
for xhr in xhr_headers_list:
print(f"XHR URL:{xhr['url']}")
print(f"XHR 头:{xhr['headers']}")
# 异步
async def filter_xhr_request_headers(page):
xhr_headers_list = []
async def handle_request(request):
if request.resource_type == "xhr":
headers = await request.all_headers()
xhr_headers_list.append({"url": request.url, "headers": headers})
page.on("request", handle_request)
await page.goto("https://example.com")
for xhr in xhr_headers_list:
print(f"XHR URL:{xhr['url']}")
场景 3:通过请求头判断请求来源
# 同步
def judge_request_origin(page):
def handle_request(request):
all_headers = request.all_headers()
# 通过Referer头判断请求来源页面
referer = all_headers.get("Referer", "直接访问")
print(f"请求 {request.url} 来自:{referer}")
# 通过Sec-Fetch-Site头判断跨域情况
fetch_site = all_headers.get("Sec-Fetch-Site", "未知")
if fetch_site == "cross-site":
print(f" 该请求为跨域请求")
elif fetch_site == "same-origin":
print(f" 该请求为同域请求")
page.on("request", handle_request)
page.goto("https://example.com")
# 异步
async def judge_request_origin(page):
async def handle_request(request):
all_headers = await request.all_headers()
referer = all_headers.get("Referer", "直接访问")
fetch_site = all_headers.get("Sec-Fetch-Site", "未知")
print(f"请求 {request.url} 来自:{referer},跨域状态:{fetch_site}")
page.on("request", handle_request)
await page.goto("https://example.com")
重要说明
- 事件监听时机:需在
page.goto()之前注册request事件监听,否则会遗漏页面初始加载的请求。 - 头名称大小写:
all_headers()返回的头名称可能为小写(如user-agent)或驼峰式(如User-Agent),建议使用dict.get()方法并忽略大小写获取指定头。 - 资源类型过滤:实际使用中可通过
request.resource_type过滤无关请求(如图片、样式、字体),聚焦核心请求(如文档、API接口)。 - 异步注意事项:异步模式下,
request事件处理函数需定义为async函数,且调用request.all_headers()时需加await。 - 重定向处理:重定向请求的
all_headers()可获取重定向时的请求头,通过redirect_from()和redirect_to()可追踪重定向链路。
要不要我帮你整理 Request 类常用操作工具函数,包含请求头筛选、API请求拦截验证、失败请求排查等可直接复用的代码片段?