Для хрома в обычном режиме можно добавить опцию и указать папку для файлов которые будут загружатся:
prefs = { “profile.default_content_settings.popups” : 0,
"download.default_directory" : os.getcwd() + “/path_to_folder/” ,
"directory_upgrade" : True }
chrome_options.add_experimental_option( “prefs” , prefs)
Но в режиме headless она не срабатывает. На StackOverflow есть подобные темы, но без решения, а если и написаны, они не рабочие. Кто-то сталкивался с такой проблемой, может есть какой-то хук для решения задачи ?
Kokoch
(Bohdan B)
02.Август.2018 12:36:18
#2
Есть решение описаное для Ruby, но актуально для любого языка - прокинуть путь через Dev tools protocol 696481 - chromium - An open-source project to help move the web forward. - Monorail
sergueik
(Сергей Кузьмин)
02.Август.2018 14:23:58
#3
вас не затруднит привести snippet, уже на java , .net или js ?
Kokoch
(Bohdan B)
02.Август.2018 20:10:45
#4
Перевод c ruby
const { id_ } = await driver.getSession()
const body = {
"cmd": "Page.setDownloadBehavior",
"params": {
"behavior": "allow",
"downloadPath": "users/blablabla/",
}
}
await fetch(`http://localhost:4444/wd/hub/session/${id_}/chromium/send_command`, {
method: 'POST',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' }
})
1 лайк
Noksa
(Alexandr D.)
03.Август.2018 05:55:45
#5
C#:
if (IsHeadless && BrowserType.ToLower() == "chrome")
{
var sessionId = DriverThreadLocal.Value.GetSessionId();
var cmd2Driver = new CmdToDriver
{
cmd = "Page.setDownloadBehavior",
ParamsInfo = new CmdToDriver.Params
{
behavior = "allow",
downloadPath = DowndloadFolder.FullName
}
};
var json = JsonConvert.SerializeObject(cmd2Driver);
var port = cds?.Port;
var url = $"http://localhost:{port}/session/{sessionId}/chromium/send_command";
var request = new RestRequest(Method.POST);
request.AddParameter("application/json", json, ParameterType.RequestBody);
request.AddHeader("Content-Type", "application/json");
request.RequestFormat = DataFormat.Json;
ApiManager.SendRequest<object>(url, request);
}
}
public class CmdToDriver
{
public string cmd { get; set; }
[JsonProperty(PropertyName = "params")]
public Params ParamsInfo {get; set; }
public class Params
{
public string behavior { get; set; }
public string downloadPath { get; set; }
}
}
public static string GetSessionId(this IWebDriver driver)
{
return ((RemoteWebDriver) driver).SessionId.ToString();
}
sergueik
(Сергей Кузьмин)
03.Август.2018 21:37:32
#6
сапсибо
пример на офмф
:
// based on:
// google chrome - Download files in Java, Selenium using ChromeDriver and headless mode - Stack Overflow
import org.json.JSONException;
import org.json.JSONObject;
private static final String chomeDriverPath = ...;
private static final String downloadFilepath = ...;
...
ChromeDriverService chromeDriverSevice = new ChromeDriverService.Builder()
.usingDriverExecutable(new File(chomeDriverPath)).usingAnyFreePort()
.build();
chromeDriverSevice.start();
driver = new ChromeDriver(chromeDriverSevice, options);
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);
JSONObject commandParamsObj = new JSONObject(commandParams);
HttpClient httpClient = HttpClientBuilder.create().build();
String payload = commandParamsObj.toString();
String u = chromeDriverSevice.getUrl().toString() + "/session/"
+ driver.getSessionId() + "/chromium/send_command";
HttpPost request = new HttpPost(u);
request.addHeader("content-type", "application/json");
request.setEntity(new StringEntity(payload));
httpClient.execute(request);
driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS);
}
@Test
public void testDownload() throws Exception {
driver.get("http://www.seleniumhq.org/download/");
driver.findElement(By.linkText("32 bit Windows IE")).click();
}
def enable_download_in_headless_chrome(br, download_dir):
# add missing support for chrome "send_command" to selenium webdriver
br.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
command_result = br.execute("send_command", params)
for key in command_result:
print("result:" + key + ":" + str(command_result[key]))
return br
chromeOptions = webdriver.ChromeOptions()
prefs = {'download.default_directory': path_for_downloads, "download.prompt_for_download": False}
chromeOptions.add_experimental_option("prefs", prefs)
if chrome_args != "":
chromeOptions.add_argument("--headless")
browser = webdriver.Chrome(chrome_driver, chrome_options=chromeOptions)
browser = enable_download_in_headless_chrome(browser, path_for_downloads)
А есть ли подобная возможность на PHP.
Эти методы для самого селениума, создайте отдельный метод и вызывайте его когда надо .
@Mastaforka А есть ли пример кода на PHP?Или ,возможно, сможете подсказать где посмотреть.
Пока примеров для PHP не нашёл.Буду очень признателен
@Vladislav1 К сожалению не подскажу реализацию на PHP
Благодаря Владу и для PHP и Codeception уже тоже есть. Может пригодиться кому:
$this->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) use (
$folder
) {
try {
$command = "Page.setDownloadBehavior";
$sessionId = $webdriver->getSessionID();
$body = ['cmd' => $command, 'params' => ['behavior' => 'allow', 'downloadPath' => $folder]];
// Тут стучимся из контейнера с кодесепшном в контейнер с хромом
$url = "http://chrome:4444/wd/hub/session/$sessionId/chromium/send_command";
$this->comment("SessionId: $sessionId");
$this->comment("Body: " . json_encode($body));
$this->comment("Url: $url");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$this->comment("Response: $response");
curl_close($ch);
} catch (Exception $e) {
$this->comment("Exception MESSAGE ERROR: " . $e . "\n");
}
});