解决 chromedp 无头模式下页面登录后的爬虫问题

博客围绕爬虫登录后捕获新页面标题的问题展开。在无头模式下捕获到的是登录页标题,有头模式正常。经多种尝试,如更改无头浏览器配置、增加睡眠时间和超时等待均无效,最终通过在捕获标题前增加元素渲染等待,等待表单元素渲染完成解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目标: 输入用户名、密码,登录后捕获新页面标题(等一系列操作)
问题: 登陆成功,无头模式下捕获到的标题仍然为登陆页面标题,有头模式下捕获到的标题为新页面标题

我的代码:

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 元素渲染完成,成功解决问题。


😍又是发现新世界的一天呢!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值