ChromeDevTools協(xié)議簡稱CDP滑潘,它允許對Chromium垢乙,Chrome和其他基于Blink的瀏覽器進行檢測,探測语卤,調(diào)試和配置追逮。許多現(xiàn)有項目目前使用該協(xié)議。 Chrome的開發(fā)者工具就是使用此協(xié)議粹舵,該團隊也負責維護其API钮孵。Chrome瀏覽器可以遠程調(diào)試的方式啟動, 實際上在瀏覽器內(nèi)部啟動了一個采用DevTools的服務器, 任何符合該協(xié)議的websoket通訊都可以被Chrome響應,這樣你可以向Chrome發(fā)送命令, 執(zhí)行操作, 實現(xiàn)一些自動化瀏覽器的操作。大名鼎鼎的ChromeDriver就是通過 DevTools Protocol實現(xiàn)與chrome瀏覽器進行交互的眼滤。
CDP官方文檔如下:
https://chromedevtools.github.io/devtools-protocol/
協(xié)議基礎
當使用--remote-debugging-port= 0參數(shù)啟動Chromium/Chrome時巴席,它啟動Chrome DevTools協(xié)議服務器并將其WebSocket URL打印到STDERR。輸出看起來像這樣:DevTools listening on ws://127.0.0.1:36775/devtools/browser/a292f96c-7332-4ce8-82a9-7411f3bd280a
客戶端可以創(chuàng)建WebSocket以連接到該URL并開始發(fā)送CDP命令诅需。 ChromeDevTools協(xié)議主要基于JSONRPC:每個命令都是一個帶有id/方法和可選參數(shù)的JavaScript結構漾唉。我們可以用如下js代碼,通過websocket協(xié)議完成與瀏覽器的交互
此腳本通過DevTools協(xié)議發(fā)送Targets.setDiscoverTargets命令诱担。瀏覽器將首先為每個現(xiàn)有目標發(fā)出一個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實現(xiàn)方案
環(huán)境搭建
從上面的例子中通過websocket與chrome直接交互實現(xiàn)是比較復雜的,因此各種主流語言都提供了類庫來簡化該過程蔫仙,詳細信息請參考:
https://github.com/ChromeDevTools/awesome-chrome-devtools#chrome-devtools-protocol
在這里我們使用python的pychrome 來實現(xiàn)與chrome的交互料睛,也可以理解我們自己開發(fā)了一個chromedriver!
Pychrome詳情請參考:https://github.com/fate0/pychrome
安裝pychrome
pip install -U pychrome
Selenium實現(xiàn)場景
實現(xiàn)場景:在百度輸入框中搜索selenium摇邦。
我們先回顧一下Selenium的代碼實現(xiàn)過程如下:
1.把chromedriver.exe放到系統(tǒng)環(huán)境變量中
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.執(zhí)行自動化腳本
Selenium的原理如下:
從上圖可知恤煞,最后是通過chromedriver完成了和chrome瀏覽器的交互!
關于selenium的詳細原理分析可以參考文章:
cdp實現(xiàn)場景
接下來我們通過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)
執(zhí)行代碼前,必須設置chrome屬性丑慎,如下圖所示:
接下來啟動chrome喜喂。
最后執(zhí)行py腳本,大家可以看到:
瀏覽器自動打開新的tab頁>在百度輸入框中搜索selenium>關閉tab頁這一過程竿裂!這也就是selenium操控瀏覽器的原理了玉吁!原創(chuàng)不易,如果文章幫到了你腻异,歡迎點贊轉發(fā)进副,讓更多的朋友受益!