2017-08-11 6 views
20

Ich benutze Python-Selen und Chrome 59 und versuche, eine einfache Download-Sequenz zu automatisieren. Wenn ich den Browser normal starte, funktioniert der Download, aber wenn ich das im Headless-Modus mache, funktioniert der Download nicht.Download mit Chrom kopflos und Selen

# 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 

Ich habe sogar versucht, einen Standardpfad hinzufügen:

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

einen Standardpfad in der normalen Ausführung arbeitet Hinzufügen, aber das gleiche Problem weiterhin besteht in der kopflose Version.

Wie kann ich den Download im Headless-Modus starten?

+0

Ich habe auch mit 'submit' und Senden von' Keys.ENTER' versucht. Es funktioniert für den normalen Browser, aber nicht für den kopflosen. – TheChetan

+0

Möchten Sie, dass es nur mit Chrom gemacht wird? oder firefox würde auch tun? –

+0

Bevorzugen Sie chrome oder phantomjs – TheChetan

Antwort

14

Dies ist eine Funktion von Chrome, um zu verhindern, dass Software Dateien auf Ihren Computer herunterlädt. Es gibt jedoch eine Problemumgehung. Read more about it here.

Was Sie tun müssen, ist es über DevTools zu ermöglichen, etwas wie folgt aus:

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

Dies ist die Lösung einige ein in der genannten Thema gab. Here is his comment.

+4

Diese Lösung erfordert, Chrome zu patchen, es ist keine Umgehungslösung. Der Befehl 'Browser.setDownloadBehavior' ist in Chrome v62.0.3186.0 ** nicht vorhanden **. –

+0

Ich bin vor ein paar Monaten in dieselbe Ausgabe gesprungen. Habe bis heute keine Lösung gefunden, dank eines Kumpels, der meine Frage kommentiert und mich hierhin weist. Das Lesen dieser Antwort macht mich glücklich, aber ich habe wirklich keine Ahnung, wie ich diesen Code in meiner Quelle kopieren oder anpassen kann. – Nihvel

+0

@Nihvel, https://Stackoverflow.com/a/36613546/4110233 könnte helfen! – TheChetan

3

Vielleicht die Website, die Sie behandeln, gibt verschiedene HTML-Seiten für Browser zurück, bedeutet die XPath oder ID, die Sie vielleicht in kopflosen Browser anders wollen. Versuchen Sie, pageSource im Headless-Browser herunterzuladen, und öffnen Sie sie als HTML-Seite, um die gewünschte ID oder den gewünschten XPath zu sehen. Sie können dies als C# -Beispiel How to hide FirefoxDriver (using Selenium) without findElement function error in PhantomDriver? sehen.

+0

empfangen Nachdem ich die Seite und ich '' Treiber.get_screenshot_as_file ('foo.png') ', bekomme ich ein Bild von der eigentlichen Sache und es sieht gut aus. Außerdem kann der Fahrer den Knopf finden. Dies untersuchen. –

8

Ja, es ist ein "Feature", für die Sicherheit. Wie bereits erwähnt, ist hier die Fehlerdiskussion: https://bugs.chromium.org/p/chromium/issues/detail?id=696481

Unterstützung wurde in Chrome Version 62.0.3196.0 oder höher hinzugefügt, um den Download zu ermöglichen.

Hier ist eine Python-Implementierung. Ich musste den Befehl zu den Chromtreiberbefehlen hinzufügen. Ich werde versuchen, eine PR einzureichen, damit sie in Zukunft in die Bibliothek aufgenommen wird.

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) 

als Referenz hier ist ein wenig Repo zu zeigen, wie diese nutzen: https://github.com/shawnbutton/PythonHeadlessChrome

+0

Das hat für mich funktioniert. Schöne Problemumgehung. –