chromedp入门
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入门的更多相关文章
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- Oracle分析函数入门
一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...
- Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数
上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...
- Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数
上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...
- Angular2入门系列教程4-服务
上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
- wepack+sass+vue 入门教程(二)
六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...
- wepack+sass+vue 入门教程(一)
一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...
随机推荐
- PIC单片机的i2c的程序
#include<pic.h>#define uchar unsigned char#define uint unsigned int#define add 0xaa__CONFIG(0x ...
- 一次FGC导致CPU飙高的排查过程
今天测试团队反馈说,服务A的响应很慢,我在想,测试环境也会慢?于是我自己用postman请求了一下接口,真的很慢,竟然要2s左右,正常就50ms左右的. 于是去测试服务器看了一下,发现服务器负载很高, ...
- Rocket - tilelink - SRAM
https://mp.weixin.qq.com/s/-z9n6SHyAiK2OE7mOSvC2Q 简单介绍SRAM的实现. 1. 基本介绍 实现一个支持读写的静态存储器.存取的 ...
- Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
小明用积木搭了一个城堡. 为了方便,小明在搭的时候用的是一样大小的正方体积本,搭在了一个 n 行 m 列的方格图上,每个积木正好占据方格图的一个小方格. 当然,小明的城堡并不是平面的,而是立体的.小明 ...
- Java实现 LeetCode 494 目标和
494. 目标和 给定一个非负整数数组,a1, a2, -, an, 和一个目标数,S.现在你有两个符号 + 和 -.对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面. 返回可 ...
- Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
算法提高 陶陶摘苹果2 时间限制:1.0s 内存限制:256.0MB 问题描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出n个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳, ...
- Android如何使用OKHttp
首先要在build.gradle里面写入 // 添加OKHttp支持 implementation("com.squareup.okhttp3:okhttp:4.3.1") 下面是 ...
- Pi-star MMDVM双工板介绍
Pi-star MMDVM双工板介绍(2020/2) pi-star里控制模式选择:双工模式(DUPLEX Mode)/单工模式(SIMPLE Mode) 双工板工作频率范围:144-148,219- ...
- (四)SQLMap之Tamper篡改脚本的类型、作用、适用场景
目录结构 一.SQLMap中tamper的简介 1.tamper的作用 2.tamper用法 二.适配不同数据库类型的测试tamper 三.SQLMap中tamper篡改脚本的功能解释 一.SQLMa ...
- cocos2dx 实现遮罩
参考博文:http://blog.csdn.net/myarrow/article/details/19913653 参考博文:http://blog.csdn.net/song_hui_xiang/ ...