英文:
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()
// 运行chromedp任务
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"]`),
// 在下面执行获取OTP的操作,这里会报错
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时出现错误。我该如何解决这个问题?
英文:
I want to automate OTP submission on a bank page. I will get the OTP in my database only after webdriver have clicked confirm on the bank page. After confirming, I need to fetch OTP from the db and then automate OTP submission.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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)
}
<!-- end snippet -->
The problem is that chromedp.Run expects all args to be of the type chromedp.Tasks, so I can't call custom functions there and I get error while fetching the OTP from db. How do I go around this?
答案1
得分: 1
解决方案是将otp获取包装在Action.Do
调用中,然后返回调用chromdp.SendKeys
设置HTML输入值的结果。
这样做是必需的,因为一次性密码在页面获取之前是不存在的,因此必须在操作资源时进行读取。
像这样
package main
import "context"
type OTPAction struct {
// DB ....
}
func (a OTPAction) Do(ctx context.Context) error {
// 在这里获取OTP
otp := "otp测试"
return chromedp.SendKeys(`//input[@id="user-message"]`, otp).Do(ctx)
}
英文:
The solution is to wrap the otp fetch within an Action.Do
call, then return the result of a call to chromdp.SendKeys
to set the HTML input value.
It is required to work that way because the One Time Password does not exist until the page was fetched, thus, its read must happen while manipulating the resource.
Like this
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论