每次看到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 # 運行命令進行測試,沒拋錯則表示正確了
https://github.com/SeleniumHQ/docker-selenium
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