Загрузка с 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