You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在chromedp中按登录状态执行不同代码并解决异常

问题原因分析
  • 未登录时偶现节点找不到报错:执行登录相关的点击、输入操作前,没有等待对应DOM节点完全渲染,页面还在加载过程中就触发操作就会返回该错误。同时使用的层级过长的选择器稳定性差,页面结构微小变动就会匹配失败。
  • 重复打开GitHub标签页:代码逻辑冗余,判断登录状态时已经完成了一次GitHub导航,后续又重复创建上下文、重复触发同地址导航,导致多开了一个标签页。
修改方案
  1. 直接复用判断登录状态时的上下文,删除冗余的targetID查询、重复上下文创建、重复导航逻辑,解决多开标签的问题。
  2. 所有DOM操作前新增WaitVisible逻辑,等待节点加载完成后再执行操作;登录提交后新增登录成功校验,确保状态正确再执行后续操作,解决偶现找不到节点的问题。
  3. 精简选择器,提升匹配稳定性。
完整修改后代码
package main

import (
	"context"
	"log"
	"time"

	"github.com/chromedp/cdproto/cdp"
	"github.com/chromedp/chromedp"
	"github.com/chromedp/chromedp/kb"
)

func main() {
	options := append(chromedp.DefaultExecAllocatorOptions[:],
		chromedp.Flag(`headless`, false),
		chromedp.DisableGPU,
		chromedp.Flag(`disable-extensions`, false),
		chromedp.Flag(`enable-automation`, false),
		chromedp.UserAgent(`Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36`),
	)

	allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), options...)
	defer cancel()

	browserCtx, cancel := chromedp.NewContext(allocCtx)
	defer cancel()

	// 原逻辑打开stackoverflow页面,按需保留即可
	if err := chromedp.Run(browserCtx,
		chromedp.Navigate("https://stackoverflow.com/questions/69672682/how-to-run-different-codes-according-to-login-status-in-chromedp"),
	); err != nil {
		log.Printf("navigate stackoverflow.com err : %v\n", err)
	}

	// 创建GitHub操作的上下文,全程复用
	githubCtx, cancel := chromedp.NewContext(browserCtx)
	defer cancel()

	var userHeaderNode []cdp.NodeID
	// 10秒超时,打开GitHub并判断登录状态
	tCtx, cancel := context.WithTimeout(githubCtx, 10*time.Second)
	defer cancel()
	if err := chromedp.Run(tCtx,
		chromedp.Navigate("https://github.com/chromedp/chromedp"),
		// 等待页面加载完成后再查询登录态节点
		chromedp.WaitReady(`body`),
		chromedp.NodeIDs(`div.Header-item.position-relative.mr-0.d-none.d-md-flex`, &userHeaderNode, chromedp.ByQuery),
	); err != nil {
		log.Printf("check login status err : %v\n", err)
	}

	// 未登录则执行登录逻辑
	if len(userHeaderNode) == 0 {
		if err := chromedp.Run(githubCtx,
			// 等待登录按钮可见再点击
			chromedp.WaitVisible(`a[href="/login"]`, chromedp.ByQuery),
			chromedp.Click(`a[href="/login"]`, chromedp.ByQuery),
			// 等待账号输入框可见再输入
			chromedp.WaitVisible(`#login_field`, chromedp.ByQuery),
			chromedp.SendKeys(`#login_field`, `XXX`),
			// 等待密码输入框可见再输入
			chromedp.WaitVisible(`#password`, chromedp.ByQuery),
			chromedp.SendKeys(`#password`, `XXX`+kb.Enter),
			// 等待登录成功,用户头象节点出现再执行后续操作
			chromedp.WaitVisible(`div.Header-item.position-relative.mr-0.d-none.d-md-flex`, chromedp.ByQuery),
		); err != nil {
			log.Printf("login err : %v\n", err)
			return
		}
	}

	// 执行切换标签版本的逻辑
	if err := chromedp.Run(githubCtx,
		chromedp.WaitVisible(`#branch-select-menu > summary`, chromedp.ByQuery),
		chromedp.Click(`#branch-select-menu > summary`, chromedp.ByQuery),
		chromedp.WaitVisible(`button.SelectMenu-tabs:nth-child(2)`, chromedp.ByQuery),
		chromedp.Click(`button.SelectMenu-tabs:nth-child(2)`, chromedp.ByQuery),
		chromedp.WaitVisible(`#tags-menu ref-selector`, chromedp.ByQuery),
		chromedp.Click(`//*[@id="tags-menu"]/ref-selector/div/div/div/a/span[text()="v0.6.6"]`, chromedp.BySearch),
		chromedp.Sleep(20*time.Second),
	); err != nil {
		log.Printf("switch tag err : %v\n", err)
	}
}

内容的提问来源于stack exchange,提问作者sSWans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:54:05