最近學web自動化時用到selenium庫,感覺很神奇,遂琢磨了一下,寫了點心得。
當我們輸入以下三行代碼並執行時,會發現新打開了一個瀏覽器窗口並訪問了百度首頁,然而這是怎么做到的呢?
1 from selenium import webdriver 2 driver = webdriver.Chrome() 3 driver.get('http://www.baidu.com')
首先我們來看一下selenium庫的結構:
很顯然,selenium就是一個軟件包,里面有兩個一級子包,common和webdriver。導入webdriver后,webdriver.Chrome()中的Chrome又是什么呢?
原來是來自二級子包chrome下的webdriver模塊里的WebDriver類,所以driver=webdriver.Chrome()中的driver是一個WebDriver類的實例化對象。我們來看看這個類:
這個類是干嘛的呢?原來它是控制谷歌瀏覽器驅動去驅動瀏覽器的,但是仔細一找,也沒看到它里面有get方法呀,哦,它繼承自RemoteWebDriver類,也就是二級子包remote下的webdriver模塊里的WebDriver類,呵呵,這還真是個高頻詞匯啊!get方法應該就在這里面,去找一下:
果然,get調用上面的execute方法,傳參,發現execute又調用了command_executor.execute方法:
繼續查看,發現command_executor.execute方法是remote_connection.py這個模塊里面的RemoteConnection類下面的,
看這個類注釋,連接到遠程瀏覽器驅動服務,很顯然,瀏覽器驅動是服務端,selenium是客戶端。在下面找到execute方法:
給遠程服務端發命令command,又將命令傳給下面的_request方法,發送HTTP請求給遠程服務端,即瀏覽器驅動,這里出現了大家熟悉的請求方法get或者post,請求url,請求體,再往上看command:
原來發的是post請求,這里使用的是WebDriver wire protocol協議,即JsonWireProtocol,body部分是這個協議規定的JSON格式的字符串。
總的來說,過程還是很復雜的,至少對於我來說。
補充:對於每一條Selenium腳本,一個http請求會被創建並且發送給瀏覽器的驅動,瀏覽器驅動中包含了一個HTTP Server,用來接收這些http請求,HTTP Server接收到請求后根據請求來具體操控對應的瀏覽器,瀏覽器執行具體的測試步驟,瀏覽器將步驟執行結果返回給HTTP Server,HTTP Server又將結果返回給Selenium的腳本,如果是錯誤的http代碼我們就會在控制台看到對應的報錯信息。