go使用chromedp模拟滑动验证登录
go使用chromedp模拟滑动验证登录
概述
在使用短效代理IP时需要获取当前IP使用量,但是官网不提供API来直接获取用量,所以想能够通过网页端登录账号、密码和滑动验证来获取登录cookie,主要难点是怎么模拟滑动验证模块,我使用的代理每天赠送1000个IP,用量不大的话免费的一般就够用了 免费代理传送门。
Chromedp
chromedp
是一个更快
、更简单
的Golang库用于调用支持Chrome DevTools协议
的浏览器,同时不需要额外的依赖(例如Selenium
和PhantomJS
)。
直接上代码
func main() {
cookies,err := XieQuCookies()
if err!=nil {
panic(err)
}
fmt.Println(cookies)
}
//获取cookie
func XieQuCookies() (string, error) {
ua:="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" options := append(chromedp.DefaultExecAllocatorOptions[:], chromedp.Flag("headless", true), // debug使用 chromedp.Flag("blink-settings", "imagesEnabled=false"), //不显示图片 chromedp.UserAgent(ua), //自定义ua ) allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), options...) defer cancel() // create context ctx, cancel := chromedp.NewContext(allocCtx,chromedp.WithLogf(log.Printf)) defer cancel() // create a timeout ctx, cancel = context.WithTimeout(ctx, 30*time.Second) defer cancel() //cookie cookiesVal:="" err := chromedp.Run(ctx, //设置webdriver检测反爬 chromedp.ActionFunc(func(cxt context.Context) error { _, err := page.AddScriptToEvaluateOnNewDocument("Object.defineProperty(navigator, 'webdriver', { get: () => false, });").Do(cxt) return err }), //登录链接 chromedp.Navigate(`https://www.xiequ.cn/iplogin.aspx`), //等待页面元素加载完成 chromedp.WaitVisible(`#nc_1_n1z`), chromedp.Sleep(time.Second*1), //账号 chromedp.SetValue(`input[name='LoginName']`, "username", chromedp.ByQuery), //密码 chromedp.SetValue(`input[name='LoginPassword']`, "123456", chromedp.ByQuery), //模拟滑动验证 chromedp.QueryAfter("#nc_1_n1z", func(fctx context.Context, id runtime.ExecutionContextID, node ...*cdp.Node) error { n:=node[0] return MouseDragNode(n, fctx) }), chromedp.Sleep(time.Millisecond*300), //点击登录 chromedp.Click(`.content1-s3-p4`, chromedp.ByQuery), chromedp.Sleep(time.Millisecond*300), //获取cookie chromedp.ActionFunc(func(cctx context.Context) error { for i:=0; i<5; i++ { cookes,err:=network.GetAllCookies().Do(cctx) if err!=nil { return err } var cookieStr bytes.Buffer for _, v := range cookes { cookieStr.WriteString(v.Name + "=" + v.Value + ";") } cookiesVal = cookieStr.String() if strings.Contains(cookiesVal,"acw_tc") { break } time.Sleep(time.Millisecond*500) } return nil }), ) return cookiesVal, err }
滑动验证
//模拟滑动
func MouseDragNode(n *cdp.Node, cxt context.Context) error {
boxes, err := dom.GetContentQuads().WithNodeID(n.NodeID).Do(cxt) if err!=nil { return err } if len(boxes) == 0 { return chromedp.ErrInvalidDimensions } content := boxes[0] c := len(content) if c%2 != 0 || c < 1 { return chromedp.ErrInvalidDimensions } var x, y float64 for i := 0; i < c; i += 2 { x += content[i] y += content[i+1] } x /= float64(c / 2) y /= float64(c / 2) p := &input.DispatchMouseEventParams{ Type: input.MousePressed, X: x, Y: y, Button: input.Left, ClickCount: 1, } // 鼠标左键按下 if err := p.Do(cxt); err != nil { return err } // 拖动 p.Type = input.MouseMoved max := 380.0 for { if p.X > max { break } rt := rand.Intn(20) + 20 chromedp.Run(cxt, chromedp.Sleep(time.Millisecond * time.Duration(rt))) x := rand.Intn(2) + 15 y := rand.Intn(2) p.X = p.X + float64(x) p.Y = p.Y + float64(y) //fmt.Println("X坐标:",p.X) if err := p.Do(cxt); err != nil { return err } } // 鼠标松开 p.Type = input.MouseReleased return p.Do(cxt) }
总结
拿到了cookie我们就可以通过cookie来获取页面中的IP使用量了。
1、页面中需要爬取的数据
2、成功获取页面的数据