Descargando con Chrome Headless y Selenium

Resuelto TheChetan asked hace 7 años • 12 respuestas

Estoy usando python-selenium y Chrome 59 e intento automatizar una secuencia de descarga simple. Cuando inicio el navegador normalmente, la descarga funciona, pero cuando lo hago en modo sin cabeza, la descarga no funciona.

# Headless implementation
from selenium import webdriver

chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_argument("headless")

driver = webdriver.Chrome(chrome_options=chromeOptions)

driver.get('https://www.mockaroo.com/')
driver.find_element_by_id('download').click()
# ^^^ Download doesn't start

# Normal Mode
from selenium import webdriver

driver = webdriver.Chrome()

driver.get('https://www.mockaroo.com/')
driver.find_element_by_id('download').click()
# ^^^ Download works normally

Incluso intenté agregar una ruta predeterminada:

prefs = {"download.default_directory" : "/Users/Chetan/Desktop/"}
chromeOptions.add_argument("headless")
chromeOptions.add_experimental_option("prefs",prefs)

Agregar una ruta predeterminada funciona en la implementación normal, pero el mismo problema persiste en la versión sin cabeza.

¿Cómo hago para que la descarga comience en modo sin cabeza?

TheChetan avatar Aug 11 '17 16:08 TheChetan
Aceptado

Sí, es una "característica" de seguridad. Como se mencionó anteriormente, aquí está la discusión sobre el error: https://bugs.chromium.org/p/chromium/issues/detail?id=696481

Se agregó soporte en la versión 62.0.3196.0 de Chrome o superior para permitir la descarga.

Aquí hay una implementación de Python. Tuve que agregar el comando a los comandos de Chromedriver. Intentaré enviar un PR para que se incluya en la biblioteca en el futuro.

def enable_download_in_headless_chrome(self, driver, download_dir):
    # add missing support for chrome "send_command"  to selenium webdriver
    driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')

    params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
    command_result = driver.execute("send_command", params)

Como referencia, aquí hay un pequeño repositorio para demostrar cómo usar esto: https://github.com/shawnbutton/PythonHeadlessChrome

actualización 2020-05-01 Ha habido comentarios que dicen que esto ya no funciona. Dado que este parche tiene más de un año, es muy posible que hayan cambiado la biblioteca subyacente.

Shawn Button avatar Nov 18 '2017 14:11 Shawn Button

Los desarrolladores de Chromium agregaron recientemente un segundo modo sin cabeza (en 2021). Consulte https://bugs.chromium.org/p/chromium/issues/detail?id=706008#c36

Posteriormente cambiaron el nombre de la opción en 2023 para Chrome 109 -> https://github.com/chromium/chromium/commit/e9c516118e2e1923757ecb13e6d9fff36775d1f4

Para Chrome 109 y superiores, la --headless=newbandera ahora le permitirá obtener la funcionalidad completa de Chrome en el nuevo modo sin cabeza, e incluso podrá ejecutar extensiones en él. (Para las versiones de Chrome 96 a 108, utilice --headless=chrome)

Uso: (Chrome 109 y superior):

options.add_argument("--headless=new")

Uso: (Chrome 96 a Chrome 108):

options.add_argument("--headless=chrome")

Si algo funciona en Chrome normal, ahora también debería funcionar con el modo sin cabeza más nuevo.

Michael Mintz avatar Sep 24 '2022 19:09 Michael Mintz