Python使用Splinter(Selenium)進行瀏覽器模擬測試

每次看到selenium都覺得很牛,但是苦于文檔(包括英文)太少,我到今天才真正完整地安裝使用了一把。我不喜歡來一個項目就在自己電腦上搭一個運行環境,而是喜歡在docker或者虛擬機里進行操作,問題是docker或者虛擬機里并沒有任何的可視化的瀏覽器,而Selenium又依賴于這些瀏覽器驅動,我是最討厭安裝驅動的,因為驅動這個東西電腦不同差距特別大,總是會出現各種問題。而在服務器上如何安裝selenium或者splinter,這個過程在網上基本是找不到的,所以這里記錄下自己的安裝方法。

注:這里之所以要使用splinter,而不只使用selenium是因為splinter在selenium之上又封裝了一層,使得接口更為簡單。

Linux install Splinter(Selenium)

首先,需要安裝必要的python包

pip3 install splinter selenium xvfbwrapper

需要注意的是,splinter只有在使用瀏覽器的時候才需要安裝selenium,如果僅僅是在flask或者django中進行測試是不需要的。

安裝chromedriver

ChromeDriver首頁-WebDriver for Chrome,下載對應操作系統的最新的chromedriver

wget http://chromedriver.storage.googleapis.com/2.23/chromedriver_linux64.zip

unzip chromedriver_linux64.zip

mv chromedriver /usr/bin # 添加到PATH即可

chromedriver # 運行命令進行測試,沒拋錯則表示正確了

Docker版本Selenium

https://github.com/SeleniumHQ/docker-selenium

handless browser

https://zhuanlan.zhihu.com/p/26810049?utm_medium=social&utm_source=qq

Linux Server(Raspberry Pi)安裝瀏覽器

上面的方式是直接打開瀏覽器的方式,但是在Server上面沒有界面,也就沒有瀏覽器,這種情況就得安裝單獨的真對server的瀏覽器了。最先我想使用ChromeDriver,但是無論怎么折騰也安裝不上,于是就用了Firefox,發現一篇很好的教程。它這個版本被稱作Selenium headless firefox。安裝步驟如下:

# 添加repository,并安裝firefox

sudo add-apt-repository ppa:mozillateam/firefox-stable

sudo apt-get update

sudo apt-get install firefox

# 安裝Xvfb: 是用來虛擬X服務程序,實現X11顯示的協議

sudo apt-get install xvfb

sudo Xvfb :10 -ac? # 10表示編號

# 設置環境變量

export DISPLAY=:10

# 就可以使用了

firefox

開始Splinter(Selenium)

無桌面環境

from splinter import Browser

from xvfbwrapper import Xvfb

from selenium.webdriver.chrome.options import Options

# 由于是在server上運行chrome,所以必須用一些模擬器

vdisplay = Xvfb()

vdisplay.start()

# 這些設置都是必要的

chrome_options = Options()

chrome_options.add_argument("--no-sandbox")

chrome_options.add_argument("--disable-setuid-sandbox")

# 這里才是正式的使用了

browser = Browser('chrome', options=chrome_options, executable_path='/root/bin/chromedriver')

browser.visit('https://haofly.net')

print(browser.title)

browser.quit()

vdisplay.stop()


桌面環境

如果直接在本地有桌面環境的情況下進行測試那么,直接這樣子:

from splinter import Browser

from selenium.webdriver.chrome.options import Options

chrome_options = Options()

browser = Browser('chrome', executable_path='/Users/haofly/share/chromedriver', user_agent='User-Agent設置', options=chrome_options)

browser.driver.set_window_size(1500, 900) # 設置瀏覽器的size

browser.visit('https://wiki.haofly.net')

print(browser.title)


Options選項

通過chrome_options.add_argument('')可以設置非常多的瀏覽器的參數

disable-infobars // 禁用網頁上部的提示欄,比如2.28的webdriver開始會提示你Chrome正受到自動測試軟件的控制,這個特性應該是chrome為了安全給加的

option.add_argument('--user-data-dir=/path') # 指定個人資料路徑,指向自己的瀏覽器,這樣,chromedriver的配置就能和自己的一樣了

獲取所有網絡請求

很多時候訪問一個頁面,在該頁面可能會同時訪問其他的資源,例如js,css,甚至其他一些關鍵信息。這時候就要求我們能夠獲取中間的所有的請求,但是selenium是不帶這個功能的,只能使用一些代理,例如:browsermob-proxy。其不需要安裝,只需要下載bin包,然后在使用的時候指定路徑即可。例如:

from browsermobproxy import Server

server = Server("~/browsermob-proxy-2.1.4/bin/browsermob-proxy")

server.start()

proxy = server.create_proxy()

chrome_options = Options()

chrome_options.add_argument('--proxy-server={host}:{port}'.format(host='localhost', port=proxy.port))

browser = Browser('chrome', executable_path='~/share/chromedriver2.28', options=chrome_options)

browser.driver.set_window_size(1500, 900) # 設置瀏覽器的size

proxy.new_har()

browser.visit('https://haofly.net')

print(proxy.har) # 以json的形式打印出中間所有的網絡請求


瀏覽器操作

browser.windows # 所有打開了的窗口

browser.windows[0] # 第一個窗口

browser.windows.current # 當前窗口

browser.windows.current = browser.windows[2] # 切換窗口

browser.window[0].close() # 關閉窗口

browser.window[0].close_others() # 關閉其他窗口

browser.window[0].is_current # 序號為零的窗口是否是當前的窗口

browser.window[0].next # 下一個窗口

browser.window[0].prev # 上一個窗口


頁面操作

browser.visit(url) # 訪問URL

browser.reload() # 重新加載當前頁

browser.back() # 回退

browser.forward() # 向前

browser.find_by_tag('h1').mouse_over() # 鼠標移動到某個元素上

browser.find_by_tag('h1').mouse_out() # 鼠標移開

browser.find_by_tag('h1').click() # 鼠標點擊事件

browser.find_ty_tag('h1').double_click()# 鼠標雙擊事件

browser.find_by_tag('h1').right_click() # 鼠標右鍵點擊

draggable = browser.find_by_tag('h1') # 鼠標拖曳事件

target = browser.find_by_css('.container')

draggable.drag_and_drop(target)

# 點擊鏈接

browser.click_link_by_href('http://www.the_site.com/my_link')

browser.click_link_by_partial_href('my_link')

browser.click_link_by_text()

browser.click_link_by_partial_text('part of link text')

browser.click_link_by_id('link_id')

# 點擊按鈕

browser.find_by_name('send').first.click()

browser.find_link_by_text('my link').first.click()

# 表單填寫

browser.fill('query', 'my name')

browser.attach_file('file', '/path/to/file/somefile.jpg')

browser.choose('some-radio', 'radio-value')

browser.check('check-name') # checkbox

browser.choose('name', 'value') # radio

browser.uncheck('some-check')

browser.select('uf', 'rj')

數據獲取

browser.title # 獲取網頁title

browser.html # 獲取網頁內容

browser.url # 獲取網頁url

browser.find_by_css('h1').first.value # 獲取元素值

browser.is_text_present('', wait_time=None)? # html里面是否存在某個字符串

# 查找css元素

browser.find_by_css('h1')

browser.find_by_xpath('//h1')

browser.find_by_tag('h1')

browser.find_by_name('name')

browser.find_by_text('Hello World!')[1]

browser.find_by_id('firstheader').last

browser.find_by_value('query').first

# 尋找網頁鏈接

browser.find_link_by_text()

browser.find_link_by_partial_text()

browser.find_link_by_href()

browser.find_link_by_partial_href()

# 可以連續用的

browser.find_by_tag('div').first.find_by_name('name')

TroubleShooting

Chrome driver crashes when opens a new tab

原因可能是服務器內存太低了,需要加大虛擬內存

selenium.common.exceptions.WebDriverException: Message: session not created exception,將webdriver更新到最新版基本上能解決問題

相關文章

Getting Started with Headless Chrome

Setting up a Digital Ocean server for Selenium, Chrome, and Python

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 這篇文章在介紹官網的同時使用了比較多的腳本示例,示例里遇到的問題有部分在本篇文章進行了解釋,還有一篇文章專門記錄了...
    顧顧314閱讀 12,963評論 3 32
  • 最近需要在一個網站下載一批數據。但是輸入一個查詢,返回三四萬條結果,每次只能導出500條,而且每次還得輸入下載條目...
    我就愛思考閱讀 26,605評論 3 25
  • # Selenium # # 自動化測試工具,致辭多種瀏覽器 # 爬蟲中主要用來解決JavaScript渲染的問題...
    拾柒丶_8257閱讀 397評論 0 0
  • Selenium 官網Selenium WebDriver官網webdriver實用指南python版本 WebD...
    顧顧314閱讀 47,054評論 0 34
  • 開了一天的會
    wuli元芳閱讀 86評論 0 0