我想在银行页面上自动提交动态口令。我将得到我的数据库中的动态口令后,只有在webdriver已经点击了银行页面上的确认。确认后,我需要从数据库中获取OTP,然后自动提交OTP。
ctx, cancel := chromedp.NewContext(context.Background(), chromedp.WithDebugf(log.Printf))
defer cancel()
// run chromedp tasks
err := chromedp.Run(ctx,
chromedp.Navigate(bankUrl),
chromedp.WaitVisible(`#username`),
chromedp.SendKeys(`#username`, `usernameXXX`),
chromedp.WaitVisible(`#label2`, ),
chromedp.SendKeys(`#label2`, `passwordxxx` ),
chromedp.Click(`//input[@title="Login"]`),
chromedp.WaitVisible(`#Go`),
chromedp.Click(`#Go`),
chromedp.WaitVisible(`#confirmButton`),
chromedp.Click(`#confirmButton`),
chromedp.WaitVisible(`//input[@type="password"]`),
// perform fetch OTP below, this raise error
otp := fetchOTPFromDb()
chromedp.SendKeys(`//input[@type="password"]`, otp),
chromedp.WaitVisible(`#confirmButton`),
chromedp.Click(`#confirmButton`))
if err != nil {
log.Fatal(err)
}
问题是chromedp.Run期望所有参数都是chromedp.Tasks类型,所以我不能在那里调用定制函数,并且在从db中获取动态口令时出现错误。我该如何解决这个问题呢?
发布于 2021-07-27 12:21:56
解决方案是将otp fetch封装在一个Action.Do
调用中,然后返回对chromdp.SendKeys
的调用结果以设置HTML输入值。
需要以这种方式工作,因为在获取页面之前,一次性密码不存在,因此,它的读取必须在操作资源时发生。
像这样
package main
import "context"
type OTPAction struct {
// DB ....
}
func (a OTPAction) Do(ctx context.Context) error {
// fetch OTP here
otp := "otp test"
return chromedp.SendKeys(`//input[@id="user-message"]`, otp).Do(ctx)
}
https://stackoverflow.com/questions/68534169
复制