chromedp入门

chromedp是什么?

chromedp是go写的,支持Chrome DevTools Protocol 的一个驱动浏览器的库。并且它不需要依赖其他的外界服务(比如 Selenium 和 PhantomJs)。

Chrome DevTools Protocol (CDP)

Chrome DevTools Protocol (CDP) 的主页在:https://chromedevtools.github.io/devtools-protocol/。 它提供一系列的接口来查看,检查,调整并且检查 Chromium 的性能。Chrome 的开发者工具就是使用这一系列的接口,并且 Chrome 开发者工具来维护这些接口。

所谓 CDP 的协议,本质上是什么呢?本质上是基于 websocket 的一种协议。比如



在我们打开 webtool 调试工具的时候,其实调试工具也是一个web页面,两个web页面通过websocket建立了一个联系。

所以我们如果写了一个客户端程序,也和目标页面创建一个基于 CDP 的 websocket连接,我们也可以通过这个协议来对页面进行操作。

如何打开 Protocol Monitor

在chrome的开发者工具中



打开实验选项 Protocol Monitor



重启chrome,在console的更多里面就可以打开对应的 Monitor

CDP 协议内容

我们从 Protocol Monitor 面板中可以看到,其中有几个字样,Method,Request,Response。

这里的 Method 就是对应官网 https://chromedevtools.github.io/devtools-protocol/ 左侧每个Domain的 Event。

这里的每个Method方法可能是调试页面给目标页面发送的,但是更多是目标页面给调试页面发送的消息。所以我们需要读懂每个Method的内容。不过很可惜,我个人感觉官网的每个Method文档的描述写的实在是太简单了,也没有看到更详细的描述,只能通过名字和事件来猜测每个Method意思了。

chromedp 使用

chromedp的使用最快的方法就是看 https://github.com/chromedp/examples 这个项目

基本我们可以熟悉最常用的几个方法了:

  • chromedp.NewContext() 初始化chromedp的上下文,后续这个页面都使用这个上下文进行操作
  • chromedp.Run() 运行一个chrome的一系列操作
  • chromedp.Navigate() 将浏览器导航到某个页面
  • chromedp.WaitVisible() 等候某个元素可见,再继续执行。
  • chromedp.Click() 模拟鼠标点击某个元素
  • chromedp.Value() 获取某个元素的value值
  • chromedp.ActionFunc() 再当前页面执行某些自定义函数
  • chromedp.Text() 读取某个元素的text值
  • chromedp.Evaluate() 执行某个js,相当于控制台输入js
  • network.SetExtraHTTPHeaders() 截取请求,额外增加header头
  • chromedp.SendKeys() 模拟键盘操作,输入字符
  • chromedp.Nodes() 根据xpath获取某些元素,并存储进入数组
  • chromedp.NewRemoteAllocator
  • chromedp.OuterHTML() 获取元素的outer html
  • chromedp.Screenshot() 根据某个元素截图
  • page.CaptureScreenshot() 截取整个页面的元素
  • chromedp.Submit() 提交某个表单
  • chromedp.WaitNotPresent() 等候某个元素不存在,比如“正在搜索。。。”
  • chromedp.Tasks{} 一系列Action组成的任务

实践

我们尝试打开 https://www.cnblogs.com/ 的首页,然后获取所有文章的标题和链接:

package main

import (
"context"
"fmt"
"log" "github.com/chromedp/cdproto/cdp"
"github.com/chromedp/chromedp"
) func main() { ctx, cancel := chromedp.NewContext(
context.Background(),
chromedp.WithLogf(log.Printf),
)
defer cancel() var nodes []*cdp.Node
err := chromedp.Run(ctx,
chromedp.Navigate("https://www.cnblogs.com/"),
chromedp.WaitVisible(`#footer`, chromedp.ByID),
chromedp.Nodes(`.//a[@class="titlelnk"]`, &nodes),
)
if err != nil {
log.Fatal(err)
} fmt.Println("get nodes:", len(nodes))
// print titles
for _, node := range nodes {
fmt.Println(node.Children[0].NodeValue, ":", node.AttributeValue("href"))
}
}

chromedp入门的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  3. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  4. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  5. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  6. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  7. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  8. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  9. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

随机推荐

  1. Github自动打包并推送Nuget版本

    如何将自己的类库,自动打包并自动发布到Nuget? 1. 项目csproject属性修改 新建一个项目GitToNugetPackageTest 不用添加任何类,我们修改csproject属性. 替换 ...

  2. [Axure教程]0001.新手入门基础

    Axure RP是一个专业的快速原型设计工具.Axure(发音:Ack-sure),代表美国Axure公司:RP则是Rapid Prototyping(快速原型)的缩写.Axure RP已被一些大公司 ...

  3. (八)Filter&ThreadLocal实现处理事务

    ConnectionContext.java package com.aff.bookstore.web; import java.sql.Connection; public class Conne ...

  4. Rocket - debug - TLDebugModuleInner - Program Buffer Access

    https://mp.weixin.qq.com/s/EJVqw7JPjjaib68tENl5AQ 简单介绍TLDebugModuleInner中的Program Buffer Access. 1. ...

  5. Chisel3 - Tutorial - ByteSelector

    https://mp.weixin.qq.com/s/RQg2ca1rwfVHx_QG-IOV-w   字节选择器.   参考链接: https://github.com/ucb-bar/chisel ...

  6. Chisel3-Intellij IDEA中使用sbt构建Chisel项目

    https://mp.weixin.qq.com/s/gssjiiPW6zUzKwCFZdNduw   1. 使用Intellij IDEA创建Scala项目   Chisel项目,就是构建Scala ...

  7. InnoSetup汉化版打包工具下载-附带脚本模板

    InnoSetup汉化版打包工具下载地址: https://www.90pan.com/b1907264 脚本模板 ; 脚本用 Inno Setup 脚本向导 生成.; 查阅文档获取创建 INNO S ...

  8. Java实现 LeetCode 763 划分字母区间(暴力)

    763. 划分字母区间 字符串 S 由小写字母组成.我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段.返回一个表示每个字符串片段的长度的列表. 示例 1: 输入: S = & ...

  9. Java实现 LeetCode 147 对链表进行插入排序

    147. 对链表进行插入排序 对链表进行插入排序. 插入排序的动画演示如上.从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示). 每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将 ...

  10. PAT 换个格式输出整数

    让我们用字母 B 来表示“百”.字母 S 表示“十”,用 12...n 来表示不为零的个位数字 n,换个格式来输出任一个不超过 3 位的正整数.例如 234 应该被输出为BBSSS1234,因为它有 ...