今天從windows環境運行了一段pyecharts的示例代碼沒有啥問題.
結果遷移到了 Ubuntu 18.04環境後竟然無法運行.代碼及錯誤信息如下:
from snapshot_selenium import snapshot as driver
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot
def bar_chart() -> Bar:
c = (
Bar()
.add_xaxis(["襯衫", "毛衣", "領帶", "褲子", "風衣", "高跟鞋", "襪子"])
.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
.reversal_axis()
.set_series_opts(label_opts=opts.LabelOpts(position="right"))
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-測試渲染圖片"))
)
return c
# 需要安裝 snapshot-selenium 或者 snapshot-phantomjs
make_snapshot(driver, bar_chart().render(), "bar.png")
錯誤信息:
Traceback (most recent call last):
File "/home/mg/github/RefUtils/src/fh_tools/language_test/pyecharts/simple_test.py", line 30, in <module>
make_snapshot(driver, bar_chart().render(), "bar.png")
File "/home/mg/github/RefUtils/venv/lib/python3.6/site-packages/pyecharts/render/snapshot.py", line 37, in make_snapshot
**kwargs,
File "/home/mg/github/RefUtils/venv/lib/python3.6/site-packages/snapshot_selenium/snapshot.py", line 35, in make_snapshot
driver = get_chrome_driver()
File "/home/mg/github/RefUtils/venv/lib/python3.6/site-packages/snapshot_selenium/snapshot.py", line 58, in get_chrome_driver
return webdriver.Chrome(options=options)
File "/home/mg/github/RefUtils/venv/lib/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 81, in __init__
desired_capabilities=desired_capabilities)
File "/home/mg/github/RefUtils/venv/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 157, in __init__
self.start_session(capabilities, browser_profile)
File "/home/mg/github/RefUtils/venv/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 252, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "/home/mg/github/RefUtils/venv/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/home/mg/github/RefUtils/venv/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally.
(unknown error: DevToolsActivePort file doesn't exist)
(The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
查了一些參考信息
從Chrome位置/ usr / bin / google-chrome開始的流程已不再運行,因此ChromeDriver假設Chrome已針對Selenium崩潰
但由於 snapshot_selenium 本身已經通過 get_chrome_driver 函數將 driver 創建的代碼封裝起來了,所以,只好直接該他的源碼了.
操作方法如下:
1) 順着代碼往源頭點開,直到
venv/lib/python3.6/site-packages/snapshot_selenium/snapshot.py
2)看到第55行的代碼 get_chrome_driver 如下
def get_chrome_driver():
options = webdriver.ChromeOptions()
options.add_argument("headless")
return webdriver.Chrome(options=options)
修改爲:
def get_chrome_driver():
options = webdriver.ChromeOptions()
options.add_argument("headless")
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
options.add_argument('--disable-dev-shm-usage')
return webdriver.Chrome(options=options)
再次運行,完美通過.
雖然修改已經安裝包的源碼不是一個好的解決方案,不過臨時處理一些,還是蠻快的.
後續改成mock的形式來解決這個問題,即可
昨天寫的一篇文章通過直接修改源碼的方式把問題解決了,不過這個方法顯然太low,而且在生產環境下也不可行.因此還是改成mock的形式進行解決.
方法如下:
from unittest import mock
def get_chrome_driver():
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("headless")
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
options.add_argument('--disable-dev-shm-usage')
return webdriver.Chrome(options=options)
from snapshot_selenium import snapshot as driver
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot
def bar_chart() -> Bar:
c = (
Bar()
.add_xaxis(["襯衫", "毛衣", "領帶", "褲子", "風衣", "高跟鞋", "襪子"])
.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
.reversal_axis()
.set_series_opts(label_opts=opts.LabelOpts(position="right"))
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-測試渲染圖片"))
)
return c
with mock.patch('snapshot_selenium.snapshot.get_chrome_driver', get_chrome_driver):
# 需要安裝 snapshot-selenium 或者 snapshot-phantomjs
make_snapshot(driver, bar_chart().render(), "bar.png")
重點是最頂部以及最底部的幾行代碼.
1)重新定義 get_chrome_driver 函數
2)通過mock方式替換 snapshot_selenium.snapshot.get_chrome_driver 函數.關鍵語句:
with mock.patch('snapshot_selenium.snapshot.get_chrome_driver', get_chrome_driver)