Golang爬虫终极杀器——Chromedp让你成为二维码登陆终结者(教程)

  1. Github源码 - chromedp
  2. 文章项目Gitee源码

1 Chromedp是什么

chromedp是一个更快更简单的Golang库用于调用支持Chrome DevTools协议的浏览器,同时不需要额外的依赖(例如SeleniumPhantomJS

Chrome和Golang都与Google有着相当密切的关系,而Chrome DevTools其实就是Chrome浏览器按下F12之后的控制终端

2 为什么不使用Selenium

对于Golang开发来说,使用chromedp更为便捷,因为它仅仅需要Chrome浏览器而并不需要依赖ChromeDriver,省去了依赖问题,有助于自动化的构建和多平台架构的迁移

3 文章解决了什么需求

  1. 如何使用chromedp进行二维码登陆
  2. 如何将二维码展示在无图形化的终端上(makiuchi-d/gozxing解码 skip2/ go-qrcode编码)
  3. 如何保存Cookies实现短时间免登陆

网站会更新,文章不保证更新,请务必学会举一反三

4 如何使用chromedp进行二维码登陆

4.1 安装chromedp

  1. 下载并安装Chrome浏览器
  2. 创建Golang项目,开启Go Module(在项目目录下使用终端输入go mod init)
  3. 在项目目录下使用终端输入:go get -u github.com/chromedp/chromedp(如果有依赖问题请删除-u

4.2 尝试打开网站(以金山文档https://account.wps.cn/为例)

  1. 重新设置chromedp使用"有头"的方式打开,以便于我们进行debug
func main(){// chromdp依赖context上限传递参数ctx, _ := chromedp.NewExecAllocator(context.Background(),// 以默认配置的数组为基础,覆写headless参数// 当然也可以根据自己的需要进行修改,这个flag是浏览器的设置append(chromedp.DefaultExecAllocatorOptions[:],chromedp.Flag("headless", false),)...,)
}
  1. 创建chromedp上下文对象
func main(){// chromdp依赖context上限传递参数...// 创建新的chromedp上下文对象,超时时间的设置不分先后// 注意第二个返回的参数是cancel(),只是我省略了ctx, _ = context.WithTimeout(ctx, 30*time.Second)ctx, _ = chromedp.NewContext(ctx,// 设置日志方法chromedp.WithLogf(log.Printf),)// 通常可以使用 defer cancel() 去取消// 但是在Windows环境下,我们希望程序能顺带关闭掉浏览器// 如果不希望浏览器关闭,使用cancel()方法即可// defer cancel()// defer chromedp.Cancel(ctx)
}
  1. 执行自定义的任务
func main(){// chromdp依赖context上限传递参数...// 创建新的chromedp上下文对象,超时时间的设置不分先后// 注意第二个返回的参数是cancel(),只是我省略了...// 执行我们自定义的任务 - myTasks函数在第4步if err := chromedp.Run(ctx, myTasks()); err != nil {log.Fatal(err)return}
}
  1. 至此程序的初始化过程已经完成,接下来就是任务——打开登陆页面
// 自定义任务
func myTasks() chromedp.Tasks {return chromedp.Tasks{// 1. 打开金山文档的登陆界面chromedp.Navigate(loginURL),}
}
  1. 运行一下程序,可以看到Chrome被打开,同时访问了我们指定的网站

4.3 获取二维码(点击过程)

  1. 需要点击微信登陆按钮,先找到按钮的选择器,右键按钮并在菜单中点击检查,然后可以看到按钮的元素

  1. 右键元素打开菜单找到copy下的copy selector,即获取到选择器

  1. 我们尝试点击微信登陆按钮,发现还需要点击一下确认,重复上述步骤获取确认按钮的选择器

  1. 用代码执行上述点击步骤
// 自定义任务
func myTasks() chromedp.Tasks {return chromedp.Tasks{// 1. 打开金山文档的登陆界面chromedp.Navigate(loginURL),// 2. 点击微信登陆按钮// #wechat > span:nth-child(2)chromedp.Click(`#wechat > span:nth-child(2)`),// 3. 点击确认按钮// #dialog > div.dialog-wrapper > div > div.dialog-footer > div.dialog-footer-okchromedp.Click(`#dialog > div.dialog-wrapper > div > div.dialog-footer > div.dialog-footer-ok`),}
}
  1. 运行程序即可直达二维码展示界面

  1. 用同样的方式,获取二维码图片选择器

  1. 用代码实现获取二维码,有两点需要注意,第一是二维码有加载过程,第二是二维码是元素渲染,我们需要用截图的方式获取(也可以用js来获取对应的href并下载,但是为了照顾小白,选择最简单的)
func myTasks() chromedp.Tasks {return chromedp.Tasks{// 1. 打开金山文档的登陆界面...// 2. 点击微信登陆按钮...// 3. 点击确认按钮...// 4. 获取二维码// #wximportgetCode(),}
}func getCode() chromedp.ActionFunc {return func(ctx context.Context) (err error) {// 1. 用于存储图片的字节切片var code []byte// 2. 截图// 注意这里需要注明直接使用ID选择器来获取元素(chromedp.ByID)if err = chromedp.Screenshot(`#wximport`, &code, chromedp.ByID).Do(ctx); err != nil {return}// 3. 保存文件if err = ioutil.WriteFile("code.png", code, 0755); err != nil {return}return}
}
  1. 执行程序即可发现目录下已经存储了二维码图片文件,我们可以通过扫描此二维码进行登陆,与浏览器上扫描为同一种效果

5. 如何将二维码展示在无图形化的终端上(与chromedp无关,属于额外内容)

  1. 在上述步骤中,我们已经获取了二维码,接下来我们需要在终端显示二维码,首先是解码,这里使用gozxing
func printQRCode(code []byte) (err error) {// 1. 因为我们的字节流是图像,所以我们需要先解码字节流img, _, err := image.Decode(bytes.NewReader(code))if err != nil {return}// 2. 然后使用gozxing库解码图片获取二进制位图bmp, err := gozxing.NewBinaryBitmapFromImage(img)if err != nil {return}// 3. 用二进制位图解码获取gozxing的二维码对象res, err := qrcode.NewQRCodeReader().Decode(bmp, nil)if err != nil {return}return
}
  1. 然后重新编码来输出二维码到终端,这里使用go-qrcode
// 请注意import的库发生了重名
import ("github.com/makiuchi-d/gozxing""github.com/makiuchi-d/gozxing/qrcode"goQrcode "github.com/skip2/go-qrcode"
)func printQRCode(code []byte) (err error) {// 1. 因为我们的字节流是图像,所以我们需要先解码字节流...// 2. 然后使用gozxing库解码图片获取二进制位图...// 3. 用二进制位图解码获取gozxing的二维码对象...// 4. 用结果来获取go-qrcode对象(注意这里我用了库的别名)qr, err := goQrcode.New(res.String(), goQrcode.High)if err != nil {return}// 5. 输出到标准输出流fmt.Println(qr.ToSmallString(false))return
}
  1. 修改我们第二步的过程
func getCode() chromedp.ActionFunc {return func(ctx context.Context) (err error) {// 1. 用于存储图片的字节切片...// 2. 截图// 注意这里需要注明直接使用ID选择器来获取元素(chromedp.ByID)...// 3. 把二维码输出到标准输出流if err = printQRCode(code); err != nil {return err}return}
}
  1. 运行程序即可查看效果

6. 如何保存Cookies实现短时间免登陆

  1. 在上述过程中,我们可以通过二维码扫描登陆,网站会在登陆之后进行跳转,跳转后我们需要保存cookies来维持我们的登录状态,代码实现如下
// 保存Cookies
func saveCookies() chromedp.ActionFunc {return func(ctx context.Context) (err error) {// 等待二维码登陆if err = chromedp.WaitVisible(`#app`, chromedp.ByID).Do(ctx); err != nil {return}// cookies的获取对应是在devTools的network面板中// 1. 获取cookiescookies, err := network.GetAllCookies().Do(ctx)if err != nil {return}// 2. 序列化cookiesData, err := network.GetAllCookiesReturns{Cookies: cookies}.MarshalJSON()if err != nil {return}// 3. 存储到临时文件if err = ioutil.WriteFile("cookies.tmp", cookiesData, 0755); err != nil {return}return}
}
  1. 获取到Cookies之后,我们需要在程序运行时将Cookies从临时文件中加载到浏览器中
// 加载Cookies
func loadCookies() chromedp.ActionFunc {return func(ctx context.Context) (err error) {// 如果cookies临时文件不存在则直接跳过if _, _err := os.Stat("cookies.tmp"); os.IsNotExist(_err) {return}// 如果存在则读取cookies的数据cookiesData, err := ioutil.ReadFile("cookies.tmp")if err != nil {return}// 反序列化cookiesParams := network.SetCookiesParams{}if err = cookiesParams.UnmarshalJSON(cookiesData); err != nil {return}// 设置cookiesreturn network.SetCookies(cookiesParams.Cookies).Do(ctx)}
}
  1. 通过上述两步我们已经可以保持登陆状态,然后我们需要检查一下是否成功,这里调用浏览器执行js脚本获取当前页面的网址,判断是否已经个人中心页面,如果为真,则停止操作
// 检查是否登陆
func checkLoginStatus() chromedp.ActionFunc {return func(ctx context.Context) (err error) {var url stringif err = chromedp.Evaluate(`window.location.href`, &url).Do(ctx); err != nil {return}if strings.Contains(url, "https://account.wps.cn/usercenter/apps") {log.Println("已经使用cookies登陆")chromedp.Stop()}return}
}
  1. 最终重新设置我们的浏览器任务即可
// 自定义任务
func myTasks() chromedp.Tasks {return chromedp.Tasks{// 0. 加载cookies <-- 变动loadCookies(),// 1. 打开金山文档的登陆界面...// 判断一下是否已经登陆  <-- 变动checkLoginStatus(),// 2. 点击微信登陆按钮// #wechat > span:nth-child(2)...// 3. 点击确认按钮// #dialog > div.dialog-wrapper > div > div.dialog-footer > div.dialog-footer-ok...// 4. 获取二维码// #wximport...// 5. 若二维码登录后,浏览器会自动跳转到用户信息页面  <-- 变动saveCookies(),}
}
  1. 我们使用已经登陆的cookies运行程序可以发现我们成功跳过登陆过程

Golang爬虫终极杀器——Chromedp让你成为二维码登陆终结者(教程)相关推荐

  1. 扫码器:壹码通(EMT 6621)二维码带多个回车换行处理

    摘要:二维码运用越来越广泛了,目前在医院中一个二维码可以串联多个系统,二维码的内容也可以设置一些特殊字符去达成系统便捷性.本次遇到为二维码中开头内置了回车和空格,在程序判断为回车(KEY_ENTER) ...

  2. Android IT新闻阅读器与手机二维码

    首先,这是一篇随笔而不是技术文章. 事情发生在一个月前,当时我苦于在路上了解不到及时的IT行业新闻,在一次偶然的机会在android手机上安装了Javaeye的新闻阅读器,有了新闻来源后,对行业中的一 ...

  3. 程序员8大终极杀器,你get了几个?

    全世界有3.14 % 的人已经关注了 数据与算法之美 经常有同学问:作为程序员,终极杀器是什么? 其实有大佬早已回答过:持续学习,开阔视野才是程序员的终极杀器!基于此,给大家一个建议:不妨多听听业内一 ...

  4. 程序员10大终极杀器,你get了几个?

    经常有同学问:作为程序员,终极杀器是什么? 其实有大佬早已回答过:持续学习,开阔视野才是程序员的终极杀器!基于此,给大家一个建议:不妨多听听业内一些大牛们的经验之谈,开阔思路,掌握高效法则黑科技. 今 ...

  5. Golang 基础案例集合:中文拼音转换、解析二维码、压缩 zip、执行定时任务

    前言 曾经,因为不够注重基础吃了好多亏.总是很喜欢去看那些高大上的东西,却忽略了最基本的东西.然后会错误的以为自己懂的很多,但是其实是沙堆中筑高台,知道很多高大上的架构,但是基础的东西却不太了解.我觉 ...

  6. golang合并支付二维码到背景图片

    [需求背景] 公司游戏要上字节小游戏,而且改用golang来作为服务端接口(之前微信小游戏是用php作为api接口的),平台对于ios游戏不支持内购支付(跟微信那些一样因为苹果分成问题).微信小游戏还 ...

  7. Golang使用qrcode生成二维码,以及生成带logo的二维码

    添加并引用依赖 go get github.com/boombuler/barcodeimport ("github.com/skip2/go-qrcode" ) 1.生成字节形式 ...

  8. python实践3——利用爬虫爬取“广州各大行业微信群二维码信息”及存入数据到MySQL数据库

    本次以"广州各大行业微信群二维码信息"为例,利用爬虫进行信息"爬取",并存入数据库,方便后面数据分析处理,以及调用.话不多说,直接上代码: [python] v ...

  9. 2021年春节过年支付宝集福神器,支付宝额外福卡二维码扫福器

    下载地址:https://www.lanzoui.com/b01br9o6j 2021年春节过年支付宝集福神器,支付宝额外福卡二维码扫福器,一年一度的集福工具又来啦! 如有杀毒软件误报,请添加信任即可 ...

最新文章

  1. 一键安装python3环境
  2. 争建AI算力中心热潮背后:谁在花冤枉钱?
  3. python手机版怎么用-QPython,一个在手机上运行Python的神器
  4. 树莓派ssh连接问题
  5. 【视频课】一课彻底掌握深度学习人脸图像算法,长期更新
  6. 客户端读写数据到HDFS的流程
  7. CentOS安装scrot记
  8. LightGBM中GBDT的实现
  9. 贪吃蛇系列之七——有吃的啦
  10. python中凯撒密码_python实现凯撒密码、凯撒加解密算法
  11. python画叮当猫_怎么画卡通哆啦A梦(机器猫、蓝胖子、叮当猫) 专家详解
  12. jeb安装教程_《教我兄弟学Android逆向番外02 jeb工具的使用》
  13. w3school离线手册
  14. 谷歌翻译(英文PDF文档翻译成中文,免费无限制)
  15. linux双硬盘硬件raid,双硬盘组建Raid0磁盘阵列图文教程
  16. 有道云笔记怎么保存html文件,有道云笔记如何保存网页有道笔记保存页面教程...
  17. SVG代码如何转为SVG文件
  18. 3dmax骨骼的绑定
  19. 英飞凌基础学习笔记(GTM)Generic Timer Module
  20. GOSSIP PROTOCOL(又被称为反熵Anti-Entropy, 一种弱一致性, 同步信息交换通信的协议)...

热门文章

  1. Unity Web自适应浏览器
  2. 学习笔记(2):走近智慧医疗,探索物联网创新应用新方向-智慧医疗 健康管理解块方案自助体检解决方案
  3. Capricorn's Trial-G
  4. 应届生嵌入式软件岗笔面试经验总结
  5. iOS下更改系统音量
  6. kriging及其加点准则学习
  7. 2019年工程造价表_2019年全国各省市公布工程造价咨询收费标准盘点
  8. 多网口网卡一键IP设置,查看网络配置、名称
  9. 为什么view的setOnClickListener引用Activity不会内存泄漏
  10. delphi 项目软件架构升级-行业软件