ChromeDevTools协议简称CDP,它允许对Chromium,Chrome和其他基于Blink的浏览器进行检测,探测,调试和配置。许多现有项目目前使用该协议。 Chrome的开发者工具就是使用此协议,该团队也负责维护其API。Chrome浏览器可以远程调试的方式启动, 实际上在浏览器内部启动了一个采用DevTools的服务器, 任何符合该协议的websoket通讯都可以被Chrome响应,这样你可以向Chrome发送命令, 执行操作, 实现一些自动化浏览器的操作。大名鼎鼎的ChromeDriver就是通过 DevTools Protocol实现与chrome浏览器进行交互的。
CDP官方文档如下:
https://chromedevtools.github.io/devtools-protocol/
协议基础
当使用--remote-debugging-port= 0参数启动Chromium/Chrome时,它启动Chrome DevTools协议服务器并将其WebSocket URL打印到STDERR。输出看起来像这样:DevTools listening on ws://127.0.0.1:36775/devtools/browser/a292f96c-7332-4ce8-82a9-7411f3bd280a
客户端可以创建WebSocket以连接到该URL并开始发送CDP命令。 ChromeDevTools协议主要基于JSONRPC:每个命令都是一个带有id/方法和可选参数的JavaScript结构。我们可以用如下js代码,通过websocket协议完成与浏览器的交互
此脚本通过DevTools协议发送Targets.setDiscoverTargets命令。浏览器将首先为每个现有目标发出一个Target.targetCreated事件,然后响应该命令:
connected!
Sending Target.setDiscoverTargets
{"method":"Target.targetCreated","params":{"targetInfo":{"targetId":"38555cfe-5ef3-44a5-a4e9-024ee6ebde5f","type":"browser","title":"","url":"","attached":true}}}
{"method":"Target.targetCreated","params":{"targetInfo":{"targetId":"52CA0FEA80FB0B98BCDB759E535B21E4","type":"page","title":"","url":"about:blank","attached":false,"browserContextId":"339D5F1CCABEFE8545E15F3C2FA5F505"}}}
{"id":1,"result":{}}
模拟chromedriver实现方案
环境搭建
从上面的例子中通过websocket与chrome直接交互实现是比较复杂的,因此各种主流语言都提供了类库来简化该过程,详细信息请参考:
https://github.com/ChromeDevTools/awesome-chrome-devtools#chrome-devtools-protocol
在这里我们使用python的pychrome 来实现与chrome的交互,也可以理解我们自己开发了一个chromedriver!
Pychrome详情请参考:https://github.com/fate0/pychrome
安装pychrome
pip install -U pychrome
Selenium实现场景
实现场景:在百度输入框中搜索selenium。
我们先回顾一下Selenium的代码实现过程如下:
1.把chromedriver.exe放到系统环境变量中
2.编写py代码
from selenium import webdriver
import unittest
class UntitledTestCase(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(30)
def test_untitled_test_case(self):
driver =self.driver
driver.get("https://www.baidu.com/")
driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
def tearDown(self):
self.driver.quit()
3.执行自动化脚本
Selenium的原理如下:
从上图可知,最后是通过chromedriver完成了和chrome浏览器的交互!
关于selenium的详细原理分析可以参考文章:
cdp实现场景
接下来我们通过cdp直接跟chrome浏览器的交互,模拟chromedriver,代码如下:
import pychrome
browser = pychrome.Browser(
url="http://127.0.0.1:9222")
#打开一个新的浏览器tabtab = browser.new_tab()
tab.start()
tab.Network.enable()
#访问baidu
tab.Page.navigate(url="https://www.baidu.com", _timeout=5)
tab.wait(5)
#在搜索框中输入selenium
tab.Runtime.evaluate(expression='document.getElementById("kw").value="selenium"')
tab.wait(1)
#点击‘百度一下’按钮
tab.Runtime.evaluate(expression='document.getElementById("su").click()')
tab.wait(5)
tab.stop()
browser.close_tab(tab)
执行代码前,必须设置chrome属性,如下图所示:
接下来启动chrome。
最后执行py脚本,大家可以看到:
浏览器自动打开新的tab页>在百度输入框中搜索selenium>关闭tab页这一过程!这也就是selenium操控浏览器的原理了!原创不易,如果文章帮到了你,欢迎点赞转发,让更多的朋友受益!