chrome python google-chrome selenium google-chrome-headless

python - chrome - Descarga con cromo sin cabeza y selenio



selenium webdriver headless python (8)

Aquí hay un ejemplo de trabajo para Python basado en la respuesta de Shawn Button . He probado esto con Chromium 68.0.3440.75 y chromedriver 2.38

from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_experimental_option("prefs", { "download.default_directory": "/path/to/download/dir", "download.prompt_for_download": False, }) chrome_options.add_argument("--headless") driver = webdriver.Chrome(chrome_options=chrome_options) driver.command_executor._commands["send_command"] = ("POST", ''/session/$sessionId/chromium/send_command'') params = {''cmd'': ''Page.setDownloadBehavior'', ''params'': {''behavior'': ''allow'', ''downloadPath'': "/path/to/download/dir"}} command_result = driver.execute("send_command", params) driver.get(''http://download-page.url/'') driver.find_element_by_css_selector("#download_link").click()

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 he intentado 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 se inicie en modo sin cabeza?


El siguiente es el equivalente en Java, selenio, chromedriver y chrome v 71.x. El código en es la clave para permitir guardar descargas Tarros adicionales: com.fasterxml.jackson.core, com.fasterxml.jackson.annotation, com.fasterxml.jackson.databind

System.setProperty ("webdriver.chrome.driver", "C: / bibliotecas / chromedriver.exe");

String downloadFilepath = "C://Download"; HashMap<String, Object> chromePreferences = new HashMap<String, Object>(); chromePreferences.put("profile.default_content_settings.popups", 0); chromePreferences.put("download.prompt_for_download", "false"); chromePreferences.put("download.default_directory", downloadFilepath); ChromeOptions chromeOptions = new ChromeOptions(); chromeOptions.setBinary("C://pathto//Chrome SxS//Application//chrome.exe"); //ChromeOptions options = new ChromeOptions(); //chromeOptions.setExperimentalOption("prefs", chromePreferences); chromeOptions.addArguments("start-maximized"); chromeOptions.addArguments("disable-infobars"); //HEADLESS CHROME **chromeOptions.addArguments("headless");** chromeOptions.setExperimentalOption("prefs", chromePreferences); DesiredCapabilities cap = DesiredCapabilities.chrome(); cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true); cap.setCapability(ChromeOptions.CAPABILITY, chromeOptions); **ChromeDriverService driverService = ChromeDriverService.createDefaultService(); ChromeDriver driver = new ChromeDriver(driverService, chromeOptions); Map<String, Object> commandParams = new HashMap<>(); commandParams.put("cmd", "Page.setDownloadBehavior"); Map<String, String> params = new HashMap<>(); params.put("behavior", "allow"); params.put("downloadPath", downloadFilepath); commandParams.put("params", params); ObjectMapper objectMapper = new ObjectMapper(); HttpClient httpClient = HttpClientBuilder.create().build(); String command = objectMapper.writeValueAsString(commandParams); String u = driverService.getUrl().toString() + "/session/" + driver.getSessionId() + "/chromium/send_command"; HttpPost request = new HttpPost(u); request.addHeader("content-type", "application/json"); request.setEntity(new StringEntity(command));** try { httpClient.execute(request); } catch (IOException e2) { // TODO Auto-generated catch block e2.printStackTrace(); }** //Continue using the driver for automation driver.manage().window().maximize();


Esta es una característica de Chrome para evitar que el software descargue archivos a su computadora. Sin embargo, hay una solución alternativa. https://bugs.chromium.org/p/chromium/issues/detail?id=696481 .

Lo que debe hacer es habilitarlo a través de DevTools, algo así:

async function setDownload () { const client = await CDP({tab: ''ws://localhost:9222/devtools/browser''}); const info = await client.send(''Browser.setDownloadBehavior'', {behavior : "allow", downloadPath: "/tmp/"}); await client.close(); }

Esta es la solución que alguien dio en el tema mencionado. Aquí está su comentario .


Por lo general, es redundante ver lo mismo escrito en otro idioma, pero debido a que este problema me volvió loco, espero salvar a alguien más del dolor ... así que aquí está la versión C # de la respuesta de Shawn Button (probada con cromo sin cabeza = 71.0.3578.98, chromedriver = 2.45.615279, plataforma = Linux 4.9.125-linuxkit x86_64)):

var enableDownloadCommandParameters = new Dictionary<string, object> { { "behavior", "allow" }, { "downloadPath", downloadDirectoryPath } }; var result = ((OpenQA.Selenium.Chrome.ChromeDriver)driver).ExecuteChromeCommandWithResult("Page.setDownloadBehavior", enableDownloadCommandParameters);


Resolví este problema usando la solución compartida por @Shawn Button y usando la ruta completa para el parámetro ''downloadPath''. Usar una ruta relativa no funcionó y me dio el error.

Versiones
Versión de Chrome 75.0.3770.100 (versión oficial) (32 bits)
ChromeDriver 75.0.3770.90


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

Se agregó soporte en la versión de Chrome 62.0.3196.0 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 RP 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



Un ejemplo de trabajo completo para JavaScript con selenium-cucumber-js / selenium-webdriver:

const chromedriver = require(''chromedriver''); const selenium = require(''selenium-webdriver''); const command = require(''selenium-webdriver/lib/command''); const chrome = require(''selenium-webdriver/chrome''); module.exports = function() { const chromeOptions = new chrome.Options() .addArguments(''--no-sandbox'', ''--headless'', ''--start-maximized'', ''--ignore-certificate-errors'') .setUserPreferences({ ''profile.default_content_settings.popups'': 0, // disable download file dialog ''download.default_directory'': ''/tmp/downloads'', // default file download location "download.prompt_for_download": false, ''download.directory_upgrade'': true, ''safebrowsing.enabled'': false, ''plugins.always_open_pdf_externally'': true, ''plugins.plugins_disabled'': ["Chrome PDF Viewer"] }) .windowSize({width: 1600, height: 1200}); const driver = new selenium.Builder() .withCapabilities({ browserName: ''chrome'', javascriptEnabled: true, acceptSslCerts: true, path: chromedriver.path }) .setChromeOptions(chromeOptions) .build(); driver.manage().window().maximize(); driver.getSession() .then(session => { const cmd = new command.Command("SEND_COMMAND") .setParameter("cmd", "Page.setDownloadBehavior") .setParameter("params", {''behavior'': ''allow'', ''downloadPath'': ''/tmp/downloads''}); driver.getExecutor().defineCommand("SEND_COMMAND", "POST", `/session/${session.getId()}/chromium/send_command`); return driver.execute(cmd); }); return driver; };

La parte clave es:

driver.getSession() .then(session => { const cmd = new command.Command("SEND_COMMAND") .setParameter("cmd", "Page.setDownloadBehavior") .setParameter("params", {''behavior'': ''allow'', ''downloadPath'': ''/tmp/downloads''}); driver.getExecutor().defineCommand("SEND_COMMAND", "POST", `/session/${session.getId()}/chromium/send_command`); return driver.execute(cmd); });

Probado con:

  • Chrome 67.0.3396.99
  • Chromedriver 2.36.540469
  • selenio-pepino-js 1.5.12
  • selenium-webdriver 3.0.0