引言: 在自動化測試以及爬蟲領域,無頭瀏覽器的應用場景非常廣泛,本文將梳理其中的若干概念和思路,並基於代碼示例其中的若干使用技巧。
1. 無頭瀏覽器
通常大家在在打開網頁的工具就是瀏覽器,通過界面上輸入網址就可以訪問相應的站點內容,這個就是通常所說的基於界面的瀏覽器。除了這種瀏覽器之外,還有一種叫做無頭瀏覽器的東西,主要是用作爬蟲,用以捕捉Web上的各類數據;這里的無頭主要是指沒有界面,完全是后台操作,對於網站來說,它以為訪問它的就是一個真實的瀏覽器。
此類的框架包括: Phantomjs為代表,其它還有非常繁多的無頭瀏覽器,大家可以自行了解一下。
2. Phantomjs
以javascript實現的一個無頭瀏覽器,兼容大多數的瀏覽器標准,本質上是一個javascript的執行引擎和解析器。通過都是以它為底層服務,然后開發第三方其它語言的適配模塊,從而打通訪問phantomjs的通道, 比如Selenium, ghostdriver.
其官方站點為: http://phantomjs.org,其支持多個平台的使用和部署。
3. Selenium
其為Web的自動化測試框架,實現了WebDriver的接口,提供了不同平台操作各類瀏覽器的接口,比如目前主流的: IE, Firefox, Chrome, Opera, Android等各個平台的訪問。
其起步階段目標是滿足自動化的需求,但其由於起特性,也可以用於頁面的瀏覽訪問,比如基於無頭瀏覽器的數據抓取和捕獲。
Selenium提供了多種語言的接口和多個平台/瀏覽器的支持,常見的有Java, Python, Javascript, Ruby等。
官方站點為:https://github.com/SeleniumHQ/selenium
4. ghostdriver
根據其官方的描述:Ghost Driver is a pure JavaScript implementation of the WebDriver Wire Protocol for PhantomJS. It's a Remote WebDriver that uses PhantomJS as back-end.
其就是一個簡要的WebDriver的實現,基於Javascript語言來實現,方便基於PhantomJS作為后端來通信。
官方地址: https://github.com/detro/ghostdriver
5. WebDriver
WebDriver是由W3C協會制定的用以描述瀏覽器行為的一組標准接口,Selenium實現其中部分的接口,大部分的瀏覽器都是以該標准來作為衡量優劣和完善與否的標准。
W3C的web driver定義: https://www.w3.org/TR/webdriver/
6. 代碼示例
讓我們通過一段代碼來看看如何基於Selenium和PhantomJS來實現自動化訪問頁面吧:
#from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
from selenium.webdriver.phantomjs.webdriver import WebDriver
# Create a new instance of the Firefox driver
driver = WebDriver(executable_path='/opt/phantomjs-2.1.1-linux-x86_64/bin/phantomjs', port=5001)
# go to the google home page
driver.get("http://www.baidu.com")
# the page is ajaxy so the title is originally this:
print(driver.title)
# find the element that's name attribute is q (the google search box)
inputElement = driver.find_element_by_id("kw")
# type in the search
inputElement.send_keys("cheese!")
# submit the form (although google automatically searches now without submitting)
inputElement.submit()
try:
# we have to wait for the page to refresh, the last thing that seems to be updated is the title
WebDriverWait(driver, 10).until(EC.title_contains("cheese!"))
# You should see "cheese! - Google Search"
print(driver.title)
print(driver.get_cookies())
finally:
driver.quit()
這里基於PhantomJS作為無頭瀏覽器的實現,WebDriver中的executable_path是放置PhantomJS的路徑。這里在頁面打開之后,輸出了title,動態輸入了cheese關鍵詞,然后點擊回車,最后打出了cookies信息。
7. API相關信息
Selenium Doc: https://seleniumhq.github.io/selenium/docs/api/py/index.html
Selenium API: https://seleniumhq.github.io/selenium/docs/api/py/api.html
Web Driver API: http://selenium-python.readthedocs.io/api.html
8. 總結
這里有一個概念需要澄清一下, Selenium原始的初衷是做基於瀏覽器的自動化測試,所以其大部分的功能都是在基於瀏覽器的訪問和接口操作,操作的都是有界面的瀏覽器;PhantomJS只是其中無界面的瀏覽器的一個實現而已了。對於不同的WebDriver接口的使用遵循上述的原則。