Загрузка с chrome без головы и Селена

Я использую python-selenium и Chrome 59 и пытаюсь автоматизировать простую последовательность загрузки. Когда я запускаю браузер нормально, загрузка работает, но когда я делаю это в безголовом режиме, загрузка не работает.

# 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

Я даже попытался добавить путь по умолчанию:

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

добавление пути по умолчанию работает в обычной реализации, но та же проблема сохраняется в безголовой версии.

как получить загрузку начать в безголовом режиме?

6 ответов


Да, это" функция " для обеспечения безопасности. Как упоминалось ранее, здесь обсуждается ошибка:https://bugs.chromium.org/p/chromium/issues/detail?id=696481

поддержка была добавлена в chrome версии 62.0.3196.0 или выше, чтобы включить загрузку.

вот реализация python. Мне пришлось добавить команду к командам chromedriver. Я постараюсь представить PR, чтобы он был включен в библиотеку в будущем.

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)

Для справки вот немного репо, чтобы продемонстрировать, как использовать это: https://github.com/shawnbutton/PythonHeadlessChrome


Это функция Chrome, чтобы предотвратить от программного обеспечения для загрузки файлов на компьютер. Однако есть обходной путь. подробнее об этом здесь:.

что вам нужно сделать, это включить его через DevTools, что-то вроде этого:

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();
}

Это решение кто-то дал в этой теме. вот его комментарий.


возможно, веб-сайт, который вы обрабатываете, возвращает разные HTML-страницы для браузеров, означает XPath или Id, который вы хотите, возможно, по-разному в безголовом браузере. Попробуйте загрузить pageSource в безголовом браузере и открыть его как HTML-страницу, чтобы увидеть Id или XPath, который вы хотите. Вы можете увидеть это как пример c#Как скрыть FirefoxDriver (используя Selenium) без ошибки функции findElement в PhantomDriver? .


вот рабочий пример для Python на основе ответ Шона Баттона. Я проверил это с помощью хром 68.0.3440.75 & 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()

полный рабочий пример для JavaScript с 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;
};

ключевая часть:

  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);
    });

протестировано с:

  • Chrome 67.0.3396.99
  • Chromedriver 2.36.540469
  • селен-огурец-js 1.5.12
  • селен-webdriver 3.0.0

Ниже приведен эквивалент в Java, selenium, chromedriver и chrome V 71.X. Код in-это ключ для сохранения загрузок Дополнительные банки: com.fasterxml.Джексон.core, com.fasterxml.Джексон.аннотация, ком.fasterxml.Джексон.метод databind