result = page.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
page.evaluate()是基础的方法,传入一个 EvaluationArgument 实现传参。
注意:为了兼容异步和同步,如果传回Promise,将会等待Promise执行完成有数据才会返回数值,所以可以在非async中正常用Promise脚本。
EvaluationArgument会自动解包,支持多种多样的脚本传参方式,可以参考官方文档:
Evaluating JavaScript | Playwright Python
# 一个基本数值
page.evaluate('num => num', 42)
# 一个数组
page.evaluate('array => array.length', [1, 2, 3])
# 传递一个对象
page.evaluate('object => object.foo', { 'foo': 'bar' })
# 传递一个句柄(ElementHandle)
# 这里用locator而不是evaluate出来的元素句柄也可以的。
button = page.evaluate('window.button')
page.evaluate('button => button.textContent', button)
# elementHandle.evaluate来替代page.evaluate,首个参数自动传elementHandle
button.evaluate('(button, from) => button.textContent.substring(from)', 5)
# 多个句柄对象
button1 = page.evaluate('window.button1')
button2 = page.evaluate('.button2')
page.evaluate("""o => o.button1.textContent + o.button2.textContent""",
{ 'button1': button1, 'button2': button2 })
# 对象解构也可以。
# 参数中对象名和结构属性名必须一致
# (括号别忘了)
page.evaluate("""
({ button1, button2 }) => button1.textContent + button2.textContent""",
{ 'button1': button1, 'button2': button2 })
# 数组也可以,解构支持任意名称,注意别忘了括号
page.evaluate("""
([b1, b2]) => b1.textContent + b2.textContent""",
[button1, button2])
# 任何可序列化对象和句柄的非嵌套循环混用都可以。
page.evaluate("""
x => x.button1.textContent + x.list[0].textContent + String(x.foo)""",
{ 'button1': button1, 'list': [button2], 'foo': None })