每次看到selenium都覺(jué)得很牛囱持,但是苦于文檔(包括英文)太少履婉,我到今天才真正完整地安裝使用了一把蚀腿。我不喜歡來(lái)一個(gè)項(xiàng)目就在自己電腦上搭一個(gè)運(yùn)行環(huán)境,而是喜歡在docker或者虛擬機(jī)里進(jìn)行操作舷嗡,問(wèn)題是docker或者虛擬機(jī)里并沒(méi)有任何的可視化的瀏覽器轴猎,而Selenium又依賴于這些瀏覽器驅(qū)動(dòng),我是最討厭安裝驅(qū)動(dòng)的进萄,因?yàn)轵?qū)動(dòng)這個(gè)東西電腦不同差距特別大捻脖,總是會(huì)出現(xiàn)各種問(wèn)題烦秩。而在服務(wù)器上如何安裝selenium或者splinter,這個(gè)過(guò)程在網(wǎng)上基本是找不到的郎仆,所以這里記錄下自己的安裝方法。
注:這里之所以要使用splinter兜蠕,而不只使用selenium是因?yàn)閟plinter在selenium之上又封裝了一層扰肌,使得接口更為簡(jiǎn)單。
Linux install Splinter(Selenium)
首先熊杨,需要安裝必要的python包
pip3 install splinter selenium xvfbwrapper
需要注意的是曙旭,splinter只有在使用瀏覽器的時(shí)候才需要安裝selenium,如果僅僅是在flask或者django中進(jìn)行測(cè)試是不需要的晶府。
安裝chromedriver
ChromeDriver首頁(yè)-WebDriver for Chrome桂躏,下載對(duì)應(yīng)操作系統(tǒng)的最新的chromedriver
wget http://chromedriver.storage.googleapis.com/2.23/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
mv chromedriver /usr/bin # 添加到PATH即可
chromedriver # 運(yùn)行命令進(jìn)行測(cè)試,沒(méi)拋錯(cuò)則表示正確了
https://github.com/SeleniumHQ/docker-selenium
https://zhuanlan.zhihu.com/p/26810049?utm_medium=social&utm_source=qq
Linux Server(Raspberry Pi)安裝瀏覽器
上面的方式是直接打開(kāi)瀏覽器的方式川陆,但是在Server上面沒(méi)有界面剂习,也就沒(méi)有瀏覽器,這種情況就得安裝單獨(dú)的真對(duì)server的瀏覽器了较沪。最先我想使用ChromeDriver鳞绕,但是無(wú)論怎么折騰也安裝不上,于是就用了Firefox尸曼,發(fā)現(xiàn)一篇很好的教程们何。它這個(gè)版本被稱作Selenium headless firefox。安裝步驟如下:
# 添加repository控轿,并安裝firefox
sudo add-apt-repository ppa:mozillateam/firefox-stable
sudo apt-get update
sudo apt-get install firefox
# 安裝Xvfb: 是用來(lái)虛擬X服務(wù)程序冤竹,實(shí)現(xiàn)X11顯示的協(xié)議
sudo apt-get install xvfb
sudo Xvfb :10 -ac? # 10表示編號(hào)
# 設(shè)置環(huán)境變量
export DISPLAY=:10
# 就可以使用了
firefox
開(kāi)始Splinter(Selenium)
from splinter import Browser
from xvfbwrapper import Xvfb
from selenium.webdriver.chrome.options import Options
# 由于是在server上運(yùn)行chrome,所以必須用一些模擬器
vdisplay = Xvfb()
vdisplay.start()
# 這些設(shè)置都是必要的
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()
桌面環(huán)境
如果直接在本地有桌面環(huán)境的情況下進(jìn)行測(cè)試那么茬射,直接這樣子:
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設(shè)置', options=chrome_options)
browser.driver.set_window_size(1500, 900) # 設(shè)置瀏覽器的size
browser.visit('https://wiki.haofly.net')
print(browser.title)
Options選項(xiàng)
通過(guò)chrome_options.add_argument('')可以設(shè)置非常多的瀏覽器的參數(shù)
disable-infobars // 禁用網(wǎng)頁(yè)上部的提示欄鹦蠕,比如2.28的webdriver開(kāi)始會(huì)提示你Chrome正受到自動(dòng)測(cè)試軟件的控制,這個(gè)特性應(yīng)該是chrome為了安全給加的
option.add_argument('--user-data-dir=/path') # 指定個(gè)人資料路徑躲株,指向自己的瀏覽器片部,這樣,chromedriver的配置就能和自己的一樣了
獲取所有網(wǎng)絡(luò)請(qǐng)求
很多時(shí)候訪問(wèn)一個(gè)頁(yè)面霜定,在該頁(yè)面可能會(huì)同時(shí)訪問(wèn)其他的資源档悠,例如js,css望浩,甚至其他一些關(guān)鍵信息辖所。這時(shí)候就要求我們能夠獲取中間的所有的請(qǐng)求,但是selenium是不帶這個(gè)功能的磨德,只能使用一些代理缘回,例如:browsermob-proxy吆视。其不需要安裝,只需要下載bin包酥宴,然后在使用的時(shí)候指定路徑即可啦吧。例如:
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) # 設(shè)置瀏覽器的size
proxy.new_har()
browser.visit('https://haofly.net')
print(proxy.har) # 以json的形式打印出中間所有的網(wǎng)絡(luò)請(qǐng)求
瀏覽器操作
browser.windows # 所有打開(kāi)了的窗口
browser.windows[0] # 第一個(gè)窗口
browser.windows.current # 當(dāng)前窗口
browser.windows.current = browser.windows[2] # 切換窗口
browser.window[0].close() # 關(guān)閉窗口
browser.window[0].close_others() # 關(guān)閉其他窗口
browser.window[0].is_current # 序號(hào)為零的窗口是否是當(dāng)前的窗口
browser.window[0].next # 下一個(gè)窗口
browser.window[0].prev # 上一個(gè)窗口
頁(yè)面操作
browser.visit(url) # 訪問(wèn)URL
browser.reload() # 重新加載當(dāng)前頁(yè)
browser.back() # 回退
browser.forward() # 向前
browser.find_by_tag('h1').mouse_over() # 鼠標(biāo)移動(dòng)到某個(gè)元素上
browser.find_by_tag('h1').mouse_out() # 鼠標(biāo)移開(kāi)
browser.find_by_tag('h1').click() # 鼠標(biāo)點(diǎn)擊事件
browser.find_ty_tag('h1').double_click()# 鼠標(biāo)雙擊事件
browser.find_by_tag('h1').right_click() # 鼠標(biāo)右鍵點(diǎn)擊
draggable = browser.find_by_tag('h1') # 鼠標(biāo)拖曳事件
target = browser.find_by_css('.container')
draggable.drag_and_drop(target)
# 點(diǎn)擊鏈接
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')
# 點(diǎn)擊按鈕
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')
數(shù)據(jù)獲取
browser.title # 獲取網(wǎng)頁(yè)title
browser.html # 獲取網(wǎng)頁(yè)內(nèi)容
browser.url # 獲取網(wǎng)頁(yè)url
browser.find_by_css('h1').first.value # 獲取元素值
browser.is_text_present('', wait_time=None)? # html里面是否存在某個(gè)字符串
# 查找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
# 尋找網(wǎng)頁(yè)鏈接
browser.find_link_by_text()
browser.find_link_by_partial_text()
browser.find_link_by_href()
browser.find_link_by_partial_href()
# 可以連續(xù)用的
browser.find_by_tag('div').first.find_by_name('name')
TroubleShooting
Chrome driver crashes when opens a new tab
原因可能是服務(wù)器內(nèi)存太低了,需要加大虛擬內(nèi)存
selenium.common.exceptions.WebDriverException: Message: session not created exception拙寡,將webdriver更新到最新版基本上能解決問(wèn)題
Getting Started with Headless Chrome
Setting up a Digital Ocean server for Selenium, Chrome, and Python