如何在 运行 使用 chromedp 的网络驱动程序时访问数据库?

How to access db while running a webdriver using chromedp?

我想在银行页面上自动提交 OTP。只有在 webdriver 在银行页面上单击确认后,我才会在我的数据库中获取 OTP。确认后,我需要从数据库中获取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 类型,所以我不能在那里调用自定义函数,并且在从数据库中获取 OTP 时出现错误。我该如何解决这个问题?

解决方案是将 otp 提取包装在 Action.Do 调用中,然后 return 调用 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)
}