selenium在使用時一直提醒換掉phantomjs 改用 chrome的headless模式,主要是因?yàn)閜hantomjs的維護(hù)已經(jīng)很少了酗失,而chrome的headless模式越來越完善嵌器。
本來只是自己研究研究,踩了幾個坑,想不到昨天線上截圖服務(wù)器出了問題痘儡,初步判斷是淘寶搞事,用js獲取當(dāng)前瀏覽器類型枢步,直接不去請求數(shù)據(jù)了沉删。
只好馬上開始換用chrome,踩了很多坑醉途,留下了悲傷的淚水矾瑰。
以下步驟可以先在windows嘗試。都兼容的
首先是chromedriver的下載隘擎,https://sites.google.com/a/chromium.org/chromedriver/ 去官網(wǎng)選最新版就好
下好后殴穴,服務(wù)器上要添加執(zhí)行權(quán)限
chmod +x chromedriver
然后安裝chromium-browser,windows本來就有chrome桌面版就可以了
這里有個坑,服務(wù)器安裝完chrome直接截圖的話采幌,中文會表現(xiàn)為方塊恍涂,所以要安裝字體包
sudo apt-get install ttf-wqy-zenhei
在windows下可以直接啟動了
browser = webdriver.Chrome(chrome_driver_path)
browser.get('http://www.reibang.com')
chrome.save_screenshot(img_name)
browser.quit()
但是服務(wù)器并沒有屏幕。很多教程比較老植榕。都是用虛擬屏幕的再沧,現(xiàn)在完全不需要了,headless模式登場
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--headless')
browser = webdriver.Chrome(chrome_driver_path)
browser.get('http://www.reibang.com')
browser.quit()
如果這時候還是報未知錯誤尊残〕慈常可能是沙盒模式啟動錯誤,添加這個關(guān)閉沙盒模式
chrome_option.add_argument('no-sandbox')
接下來是代理設(shè)置寝衫,普通的http代理很簡單顷扩,proxy為'http://ip:port'這樣的形式
chrome_option.add_argument('--proxy-server={}'.format(proxy))
可是https就有問題了。需要關(guān)閉chrome的證書認(rèn)證慰毅,找了很久隘截,終于找到了解決方案,原來之前headless模式一直沒有實(shí)現(xiàn)這個功能汹胃,直到半個月前才有消息
圍觀大佬 https://bugs.chromium.org/p/chromium/issues/detail?id=721739#c60
于是有了解決方案婶芭,= = 找了好久啊,注意這里的版本是有限制的 chroem >= 65 chromedriver>2.35 反正最新版就對了
# 配置忽略ssl錯誤
capabilities = DesiredCapabilities.CHROME.copy()
capabilities['acceptSslCerts'] = True
capabilities['acceptInsecureCerts'] = True
browser = webdriver.Chrome(desired_capabilities=capabilities)
還有一個坑,chrome直接設(shè)置超時會使瀏覽器崩潰着饥,導(dǎo)致無法進(jìn)行下去犀农,像我的需求,載入了一段時間后還是想停止載入并截圖的
20180414 更新
我之前這里寫的是用調(diào)用插件的辦法宰掉,但是仔細(xì)研究后呵哨,現(xiàn)在chrome headless 還不支持插件,不過普通的在頁面加載前執(zhí)行js還是可以的轨奄,就是沒有那么高的權(quán)限
def send(driver, cmd, params={}):
resource = "/session/%s/chromium/send_command_and_get_result" % driver.session_id
url = driver.command_executor._url + resource
body = json.dumps({'cmd': cmd, 'params': params})
response = driver.command_executor._request('POST', url, body)
if response['status']:
raise Exception(response.get('value'))
return response.get('value')
def add_script(driver, script):
send(driver, "Page.addScriptToEvaluateOnNewDocument", {"source": script})
WebDriver.add_script = add_script
browser = webdriver.Chrome('./chromedriver', chrome_options=chrome_option)
assert isinstance(browser, WebDriver)
browser.add_script("""
setInterval(function () {document.title = 'sb sb'}, 1000);
""")
想要插件的高權(quán)限只能不用headless模式了
最后是完整代碼
class get_chroem:
def __init__(self, *args, **kwargs):
self.browser = None
self.args = args
self.kwargs = kwargs
self.window_size = None
def _get_chrome(self, type, use_proxy):
chrome_option = webdriver.ChromeOptions()
user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
self.window_size = ('1440', '900')
chrome_option.add_argument('--proxy-server={}'.format(proxy))
chrome_option.add_argument('no-sandbox')
chrome_option.add_argument('--headless')
# 配置忽略ssl錯誤
capabilities = DesiredCapabilities.CHROME.copy()
capabilities['acceptSslCerts'] = True
capabilities['acceptInsecureCerts'] = True
browser = webdriver.Chrome(
chrome_driver_path,
chrome_options=chrome_option,
# service_log_path='/opt/logs/chrome.log',
desired_capabilities=capabilities)
if self.window_size is not None:
browser.set_window_size(*self.window_size)
return browser
def __enter__(self):
"""
:rtype: selenium.webdriver.chrome.webdriver.WebDriver
:return:
"""
self.browser = self._get_chrome(*self.args, **self.kwargs)
return self.browser
def __exit__(self, exc_type, exc_value, traceback):
if self.browser is None:
return
try:
self.browser.quit()
except:
pass
用with語法調(diào)用口味更佳
# 截圖
chrome.save_screenshot(img_name)