Selenium + ChromeDriver printToPDF

Есть ли способ вызвать Page.printToPDF () chromedriver метод из питона + селена?

PhantomJS имеет аналогичный метод render (), который можно сохранять прямо в pdf, т.е. доступно только из привилегированного клиентского REPL phantomjs. Этот ответ SO показывает, как исправить работающий драйвер селена для его вызова с помощью специальной команды webdriver phantomjs (/session/$sessionId/phantom/execute) для вызова this.render().

Есть ли что-то подобное, что можно сделать для хромодрайвера? Либо что-то вроде команды phantomjs execute, которая позволяет вызывать методы devtools; или способ вызвать printToPDF напрямую с помощью специальной команды драйвера?

(Примечание: я пытаюсь отобразить html, который является результатом POST, поэтому альтернативные решения, такие как wkhtmltopdf, не будут работать. Я могу вернуться к использованию снимка экрана селена -> png, но это обременительно для целей хранения) < / em>.


person Eli Collins    schedule 30.10.2017    source источник


Ответы (2)


Это возможно, вызвав Page.printToPDF из DevTool API. Однако эта команда является экспериментальной и реализована не на всех платформах:

from selenium import webdriver
import json, base64

def send_devtools(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 save_as_pdf(driver, path, options={}):    
  # https://timvdlippe.github.io/devtools-protocol/tot/Page#method-printToPDF
  result = send_devtools(driver, "Page.printToPDF", options)
  with open(path, 'wb') as file:
    file.write(base64.b64decode(result['data']))


options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--disable-gpu")

driver = webdriver.Chrome(chrome_options=options)
driver.get("https://www.google.co.uk/")

save_as_pdf(driver, r'page.pdf', { 'landscape': False })
person Florent B.    schedule 30.10.2017
comment
Спасибо, именно то, что я искал! Хотя я получаю сообщение об ошибке PrintToPDF is not implemented. Что мне нужно сделать, чтобы включить экспериментальные функции? (Selenium сообщает, что подключается к Chrome 62.0.3202.62, ChromeDriver 2.32, Platform = Linux). Насколько я могу судить, эта версия должна (?) иметь поддержку printToPDF. - person Eli Collins; 31.10.2017
comment
Попробуйте использовать канареечную версию или последнюю версию от woolyss (64.0.3249.0) - person Florent B.; 31.10.2017
comment
Ах, выследил. Согласно документам printToPDF кукловода, в настоящее время он доступен только в безголовый режим. Все работает идеально, как только я включаю его. - person Eli Collins; 31.10.2017

Хорошо, только для справки, вот как я заставил его работать в 2019 году без создания исключения:

def send_devtools(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)
    #print (response)
    if (response.get('value') is not None):
        return response.get('value')
    else:
        return None

def save_as_pdf(driver, path, options={}):
    # https://timvdlippe.github.io/devtools-protocol/tot/Page#method-printToPDF
    result = send_devtools(driver, "Page.printToPDF", options)
    if (result is not None):
        with open(path, 'wb') as file:
            file.write(base64.b64decode(result['data']))
        return True
    else:
        return False
person Caio Pedreira    schedule 15.08.2019
comment
Добро пожаловать в SO! Пожалуйста, отредактируйте свой ответ и немного объясните контекст и почему это возможно. Дополнительные инструкции см. На странице stackoverflow.com/help/how-to-answer. - person B--rian; 15.08.2019