chromedp 获取新选项卡内容
/**
* 使用 chromedp 监听新标签页的功能
*/
package main
import (
"context"
"/chromedp/cdproto/target"
"/chromedp/chromedp"
"log"
"net/http/httptest"
"time"
)
// addNewTabListener 注册新标签页的监听服务并返回新标签页的 ID 通道
func addNewTabListener(ctx context.Context) <-chan target.ID {
// 创建一个 HTTP 服务器用于监听新标签页
mux := http.NewServeMux()
ts := httptest.NewServer(mux)
defer ts.Close() // 确保服务器在退出时得到关闭
// 监听新目标的创建,当新标签页的 URL 不为空时返回
return chromedp.WaitNewTarget(ctx, func(info *target.Info) bool {
return info.URL != ""
})
}
// configureChromeOptions 设置 Chrome 启动参数
func configureChromeOptions() []chromedp.ExecAllocatorOption {
return append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.NoDefaultBrowserCheck, // 不检查默认浏览器
chromedp.Flag("headless", false), // 启用可视化界面
chromedp.Flag("ignore-certificate-errors", true), // 忽略证书错误
chromedp.Flag("disable-web-security", true), // 禁用网络安全设置
chromedp.Flag("disable-extensions", false), // 开启扩展支持
chromedp.Flag("disable-default-apps", false),
chromedp.NoFirstRun, // 不是首次运行
chromedp.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36"),
)
}
// main 主函数,程序的入口
func main() {
// 创建执行上下文
allocCtx, _ := chromedp.NewExecAllocator(context.Background(), configureChromeOptions()...)
ctx, _ := chromedp.NewContext(allocCtx, chromedp.WithLogf(log.Printf))
// 添加新标签页监听
newTabChan := addNewTabListener(ctx)
// 执行爬虫任务
err := chromedp.Run(ctx,
chromedp.Navigate("/dashboard/live/control"),
chromedp.Sleep(3*time.Second),
chromedp.WaitReady(`._1M2DJMjmtJZhkk7ei5nC9F`, chromedp.ByQuery),
chromedp.Sleep(5*time.Second),
chromedp.Click(`._1M2DJMjmtJZhkk7ei5nC9F`, chromedp.ByQuery, chromedp.NodeNotVisible), // 点击链接打开新标签
)
if err != nil {
log.Fatal(err)
}
// 获取新标签页的上下文
newCtx, _ := chromedp.NewContext(ctx, chromedp.WithTargetID(<-newTabChan))
// 新标签页执行任务,获取内容
var res string
err = chromedp.Run(newCtx,
chromedp.WaitReady(`#app`, chromedp.ByID),
chromedp.Text(`#app`, &res, chromedp.NodeVisible, chromedp.ByID),
)
if err != nil {
log.Fatal(err)
}
// 输出获取到的内容
log.Println(res)
}