Altair automati c сохранить диаграмму, используя хромедривер селена - PullRequest
1 голос
/ 24 января 2020

Снова спрашивая, как предыдущий был закрыт без какого-либо полезного решения.

Я пытаюсь создать несколько диаграмм в al oop и сохранить их автоматически.

Я работаю над Windows, используя Chrome.

Я следовал документации о том, как сохранить диаграмму в svg.

Я скачал соответствующий ChromeDriver для моей Chrome версии. gdf - это мой геоданный, и все работает гладко, и я могу создавать и сохранять диаграммы вручную.

Кроме того, этот пример, взятый из документации по хрому, работает:

import time
from selenium import webdriver

driver = webdriver.Chrome('pathtochromedriver/chromedriver_win32/chromedriver.exe')
driver.get('http://www.google.com/');
time.sleep(5) # Let the user actually see something!
search_box = driver.find_element_by_name('q')
search_box.send_keys('ChromeDriver')
search_box.submit()
time.sleep(5) # Let the user actually see something!
driver.quit()

Ниже приведен фрагмент код, который я пытаюсь запустить:

#Chromedriver for headless run and chart automatic save
from selenium import webdriver
from selenium.webdriver.chrome.options import Options 

chrome_options = Options()  
chrome_options.add_argument("--headless") 
####### None of the following work! 
#driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=r'pathtochromedriver/chromedriver_win32/chromedriver.exe')
#driver = webdriver.Chrome(executable_path=r'pathtochromedriver/chromedriver_win32/chromedriver.exe')
driver = webdriver.Chrome('pathtochromedriver/chromedriver_win32/chromedriver.exe')
#
#loop
for group in gdf['Group Name'].unique():
    map_1km_json = json.loads(gdf[gdf['Group Name']==group].to_json())
    map_1km_data = alt.Data(values=map_1km_json['features'])
    data_1km_geojson = alt.InlineData(values=map_1km, format=alt.DataFormat(property='features',type='json'))
    domain=[1,2]
    range_=['#b0d247','#007bd1']
    choro1_5 = alt.Chart(map_1km_data).mark_geoshape().encode(
        alt.Color('properties.Cat2:O', scale=alt.Scale(domain=domain, range=range_),title = "Havvandsstigning"),
        #alt.Color('properties.Cat2', type='quantitative', scale=alt.Scale(scheme='plasma'),title = "Havvandsstigning")
        tooltip = ['properties.dd_km1:N','properties.Cat2:N']
    ).properties(
    width=1100,
    height=800
    )
    (background + choro1_5).save("{}.svg".format(bank))
driver.quit()

При запуске кода открывается новая пустая chrome панель (в фоновом режиме), которая выглядит следующим образом, что намекает на то, что chromedriver работает гладко: chromepane

Но код возвращает следующую ошибку:

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
~\Anaconda3\lib\site-packages\selenium\webdriver\common\service.py in start(self)
     75                                             stderr=self.log_file,
---> 76                                             stdin=PIPE)
     77         except TypeError:

~\Anaconda3\lib\subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors, text)
    774                                 errread, errwrite,
--> 775                                 restore_signals, start_new_session)
    776         except:

~\Anaconda3\lib\subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_start_new_session)
   1177                                          os.fspath(cwd) if cwd is not None else None,
-> 1178                                          startupinfo)
   1179             finally:

FileNotFoundError: [WinError 2] The system cannot find the file specified

During handling of the above exception, another exception occurred:

WebDriverException                        Traceback (most recent call last)
<ipython-input-27-6067387e4b2f> in <module>
     19     height=800
     20     )
---> 21     (background + choro1_5).save("{}.svg".format(bank))
     22 driver.quit()

~\Anaconda3\lib\site-packages\altair\vegalite\v3\api.py in save(self, fp, format, override_data_transformer, scale_factor, vegalite_version, vega_version, vegaembed_version, **kwargs)
    478         if override_data_transformer:
    479             with data_transformers.disable_max_rows():
--> 480                 result = save(**kwds)
    481         else:
    482             result = save(**kwds)

~\Anaconda3\lib\site-packages\altair\utils\save.py in save(chart, fp, vega_version, vegaembed_version, format, mode, vegalite_version, embed_options, json_kwds, webdriver, scale_factor, **kwargs)
    102                                         vegaembed_version=vegaembed_version,
    103                                         webdriver=webdriver,
--> 104                                         scale_factor=scale_factor, **kwargs)
    105         if format == 'png':
    106             write_file_or_filename(fp, mimebundle['image/png'], mode='wb')

~\Anaconda3\lib\site-packages\altair\utils\mimebundle.py in spec_to_mimebundle(spec, format, mode, vega_version, vegaembed_version, vegalite_version, **kwargs)
     54                               vega_version=vega_version,
     55                               vegaembed_version=vegaembed_version,
---> 56                               vegalite_version=vegalite_version, **kwargs)
     57         if format == 'png':
     58             render = base64.b64decode(render.split(',', 1)[1].encode())

~\Anaconda3\lib\site-packages\altair\utils\headless.py in compile_spec(spec, format, mode, vega_version, vegaembed_version, vegalite_version, scale_factor, driver_timeout, webdriver)
    152             webdriver_options.add_argument('--no-sandbox')
    153 
--> 154     driver = webdriver_class(options=webdriver_options)
    155 
    156     try:

~\Anaconda3\lib\site-packages\selenium\webdriver\chrome\webdriver.py in __init__(self, executable_path, port, options, service_args, desired_capabilities, service_log_path, chrome_options, keep_alive)
     71             service_args=service_args,
     72             log_path=service_log_path)
---> 73         self.service.start()
     74 
     75         try:

~\Anaconda3\lib\site-packages\selenium\webdriver\common\service.py in start(self)
     81                 raise WebDriverException(
     82                     "'%s' executable needs to be in PATH. %s" % (
---> 83                         os.path.basename(self.path), self.start_error_message)
     84                 )
     85             elif err.errno == errno.EACCES:

WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

Ответы [ 2 ]

3 голосов
/ 28 января 2020

Причина, по которой ваш код не работает, заключается в том, что вы не передаете свой экземпляр драйвера в Altair, и поэтому Altair создает экземпляр драйвера по умолчанию и ищет chromedriver в расположении по умолчанию.

В настоящее время Altair не работает поддерживает передачу пользовательского экземпляра драйвера в метод save(), поэтому сохранение фигуры способом, который вы пытаетесь выполнить выше, невозможно, если только хромодрайвер не может быть сделан доступным в расположении по умолчанию.

Мы находимся в процессе для улучшения этого, однако, с пакетом altair_saver . С его помощью вы можете передать пользовательский экземпляр драйвера методу сохранения:

from altair_saver import save

# ...

chart = background + choro1_5
filename = f"{bank}.svg"
save(chart, filename, method='selenium', webdriver=driver)

В будущем выпуске Altair это более гибкое расширение заставки заменит текущий встроенный метод Altair chart.save().

2 голосов
/ 27 января 2020

Посмотрите на проект Altair Saver . Он использует Chrome Driver и Selenium. Установить через пип или конду. Это может сохранить в SVG:

from altair_saver import save

save((background + choro1_5), "{}.svg".format(bank))
...