目标: 输入用户名、密码,登录后捕获新页面标题(等一系列操作)
问题: 登陆成功,无头模式下捕获到的标题仍然为登陆页面标题,有头模式下捕获到的标题为新页面标题
我的代码:
func main() {
//配置
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.DisableGPU, //禁用 GPU 进程 (--disable-gpu)
chromedp.NoDefaultBrowserCheck, //不检查默认浏览器
chromedp.Flag("headless", true), //开启图像界面
chromedp.Flag("ignore-certificate-errors", true), //忽略错误
chromedp.Flag("disable-web-security", true), //禁用网络安全标志
chromedp.Flag("disable-extensions", false), //开启插件支持
chromedp.Flag("disable-default-apps", false),
chromedp.Flag("no-sandbox", true), // 取消沙盒模式
chromedp.Flag("disable-dev-shm-usage", true),
chromedp.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"),
chromedp.WindowSize(1920, 1080),
)
//创建上述自定义的context
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
defer cancel()
log.Println("自定义 context :", allocCtx)
//初始化 Chrome 实例,ctx为Chrome实例对象,cancel为取消函数
ctx, cancel := chromedp.NewContext(
allocCtx, //自定义模式
chromedp.WithLogf(log.Printf),
)
defer cancel()
// start the browser without a timeout
if err := chromedp.Run(ctx); err != nil {
log.Fatal(err)
}
ExampleURL(ctx, `填写登录网址`)
ExampleSubmit(ctx)
ExampleTitle(ctx)
}
// 地址加载
func ExampleURL(ctx context.Context, url string) {
err := chromedp.Run(ctx,
chromedp.Navigate(url),
)
if err != nil {
log.Fatal("连接失败,失败信息:", err)
}
log.Println("加载成功!")
}
//表单提交
func ExampleSubmit(ctx context.Context) {
if err := chromedp.Run(ctx,
chromedp.SendKeys(`复制 用户名输入框 的selector`, `填写要输入的用户名`),
chromedp.SendKeys(`复制 密码处输入框 的selector`, `填写要输入的密码`),
chromedp.Click(`复制 提交按钮 的selector`),
); err != nil {
log.Println(err)
}
log.Println("成功!")
}
// 捕获title信息
func ExampleTitle(ctx context.Context) {
var title string
if err := chromedp.Run(ctx,
chromedp.Title(&title)); err != nil {
log.Fatal("捕获title信息失败,失败信息:", err)
}
log.Println("网页标题:", title)
}
解决: 仅在捕获标题函数中新增一条
// 捕获title信息
func ExampleTitle(ctx context.Context) {
var title string
if err := chromedp.Run(ctx,
chromedp.WaitReady("form"), //新增
chromedp.Title(&title)); err != nil {
log.Fatal("捕获title信息失败,失败信息:", err)
}
log.Println("网页标题:", title)
}
原因探索:
网上很多说是无头浏览器配置问题,我也更改尝试了,仍未解决问题;
这个原因我是在断点测试时发现的,直接运行捕获不到新页面,但如果在表单提交后的 “成功”语句打印( log.Println("成功!")
)处打断点,依次执行则能够捕获到新页面;
因此,我怀疑是标题捕获时页面未渲染完成,然后我尝试了增加睡眠时间、增加超时等待,都没有效果;
WaitReady is an element query action that waits until the element matching the selector is ready (i.e., has been “loaded”).
这是 WaitReady
的官方解释。尝试在捕获标题信息前增加 元素渲染等待 ,等待表单 form
元素渲染完成,成功解决问题。
😍又是发现新世界的一天呢!!