Golang中chromedp.Poll与PollFunction的使用方法
Golang中chromedp.Poll与PollFunction的使用方法 我正在评估JavaScript以确定页面是否完全加载。我目前正在使用chromedp.Evaluate,并发现使用chromedp.Poll或chromedp.PollFunction函数可以减少代码量。
然而,我尝试了这两种方法都没有成功:
const ( pollFunction = ` function isInitialized(logMessage) { if(typeof globalThis.logger === ‘undefined’) { console.log(‘logger is undefined’); return false; }
console.log(‘checking logs’); return globalThis.logger.dump().some(log => typeof log === ‘string’ && log.includes(logMessage));
} `
pollStatement =
typeof globalThis.logger !== 'undefined' && globalThis.logger.dump().some(log => typeof log === 'string' && log.includes('%s')))
这会导致超时:
chromedp.Run(ctx, chromedp.Poll(fmt.Sprintf(pollStatement, logMessage), nil, chromedp.WithPollingArgs(logMessage), chromedp.WithPollingInterval(pollInterval), chromedp.WithPollingTimeout(pollTimeout)))
我尝试了函数和内联语句两种方式。使用函数时,我希望能看到一些语句打印到控制台,但什么也没有得到。
虽然我使用Evaluate的版本可以工作,但我需要自己进行轮询。如果有更好的方法,我希望使用它。
Poll和PollFunction的参考资料:puppeteer/docs/api.md at v8.0.0 · puppeteer/puppeteer · GitHub,并且我已经尝试了各种语法变体,以查看是否是语法错误。
更多关于Golang中chromedp.Poll与PollFunction的使用方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我想我已经解决了这个问题,我传入了错误的上下文。上面的代码仍然是正确的,但那是在一个函数中,并且该函数被错误地调用了。
我传入了原始的上下文,该上下文的时间限制是5秒,但它启动得更早,而我等待的那个真值大约需要10秒才能返回,这就是它从未成功的原因。
更多关于Golang中chromedp.Poll与PollFunction的使用方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在chromedp中使用Poll和PollFunction时,需要注意JavaScript执行上下文和参数传递的正确方式。以下是两种方法的具体实现:
1. 使用PollFunction的正确方式
// 定义JavaScript函数
const pollFunction = `
function isInitialized(logMessage) {
if (typeof globalThis.logger === 'undefined') {
console.log('logger is undefined');
return false;
}
console.log('checking logs for:', logMessage);
const logs = globalThis.logger.dump();
return logs.some(log => typeof log === 'string' && log.includes(logMessage));
}
`
func waitForLogMessage(ctx context.Context, logMessage string) error {
return chromedp.Run(ctx,
chromedp.PollFunction(
pollFunction,
func(result *runtime.RemoteObject) bool {
if result.Type == "boolean" && result.Value == true {
return true
}
return false
},
chromedp.WithPollingArgs(logMessage),
chromedp.WithPollingInterval(1*time.Second),
chromedp.WithPollingTimeout(30*time.Second),
),
)
}
2. 使用Poll的正确方式
func waitForLogMessagePoll(ctx context.Context, logMessage string) error {
// 使用模板字符串避免注入问题
pollStatement := `
(function(logMessage) {
if (typeof globalThis.logger === 'undefined') {
console.log('logger is undefined');
return false;
}
const logs = globalThis.logger.dump();
return logs.some(log => typeof log === 'string' && log.includes(logMessage));
})("%s")
`
return chromedp.Run(ctx,
chromedp.Poll(
fmt.Sprintf(pollStatement, logMessage),
nil,
chromedp.WithPollingInterval(1*time.Second),
chromedp.WithPollingTimeout(30*time.Second),
),
)
}
3. 更简洁的PollFunction示例
func waitForElementReady(ctx context.Context) error {
return chromedp.Run(ctx,
chromedp.PollFunction(
`() => {
const element = document.querySelector('#myElement');
if (!element) return false;
return element.offsetWidth > 0 && element.offsetHeight > 0;
}`,
func(result *runtime.RemoteObject) bool {
return result.Type == "boolean" && result.Value == true
},
chromedp.WithPollingInterval(500*time.Millisecond),
chromedp.WithPollingTimeout(10*time.Second),
),
)
}
4. 带参数的PollFunction示例
func waitForSpecificText(ctx context.Context, selector, expectedText string) error {
return chromedp.Run(ctx,
chromedp.PollFunction(
`(selector, expectedText) => {
const element = document.querySelector(selector);
if (!element) return false;
return element.textContent.includes(expectedText);
}`,
func(result *runtime.RemoteObject) bool {
return result.Type == "boolean" && result.Value == true
},
chromedp.WithPollingArgs(selector, expectedText),
chromedp.WithPollingInterval(1*time.Second),
chromedp.WithPollingTimeout(20*time.Second),
),
)
}
5. 调试版本(添加日志输出)
func waitForLogMessageDebug(ctx context.Context, logMessage string) error {
debugFunction := `
function checkLogs(logMessage) {
console.log('PollFunction called with message:', logMessage);
if (typeof globalThis.logger === 'undefined') {
console.log('DEBUG: logger is undefined');
return false;
}
console.log('DEBUG: logger exists, checking logs...');
const logs = globalThis.logger.dump();
console.log('DEBUG: logs count:', logs.length);
const found = logs.some(log => {
if (typeof log === 'string') {
const includes = log.includes(logMessage);
if (includes) console.log('DEBUG: Found matching log:', log);
return includes;
}
return false;
});
console.log('DEBUG: result:', found);
return found;
}
`
return chromedp.Run(ctx,
chromedp.PollFunction(
debugFunction,
func(result *runtime.RemoteObject) bool {
fmt.Printf("Go received result: Type=%s, Value=%v\n",
result.Type, result.Value)
return result.Type == "boolean" && result.Value == true
},
chromedp.WithPollingArgs(logMessage),
chromedp.WithPollingInterval(2*time.Second),
chromedp.WithPollingTimeout(60*time.Second),
),
)
}
关键点:
PollFunction需要返回一个函数,而不是函数定义字符串- 参数通过
WithPollingArgs传递,在JavaScript函数中作为参数接收 Poll直接执行JavaScript表达式,需要返回布尔值- 确保JavaScript代码在浏览器上下文中能正确执行
- 使用适当的轮询间隔和超时时间

