Dostęp do okna pobierania plików w przeglądarce Firefox

83

Czy istnieje interfejs API, który pozwala mi manipulować oknem dialogowym pobierania plików w przeglądarce Firefox? (Chcę uzyskać dostęp do tego, który pojawia się, gdy użytkownik coś robi, a nie sam inicjować).

To, co chcę zrobić, to uzyskać dostęp do tego okna dialogowego z Selenium (i nie jestem pewien, czy "tryb uprzywilejowany" Selenium wystarczy, aby uzyskać dostęp do interfejsu chrome).

Andrey Shchekin
źródło
3
Właśnie spędziłem większą część trzech tygodni na konfigurowaniu mojego własnego wirtualnego prywatnego serwera Apache po raz pierwszy (ponieważ uruchamianie Selenium na współdzielonym hostingu jest trochę trudne), sprawiając, że Firefox, Selenium i Python współpracują ze sobą, pisząc rzeczywisty kod Pythona do step przez bardzo bogatą w JavaScript witrynę, wszystko po to, aby pobrać plik na końcu. Wtedy zdałem sobie sprawę, że nie mam pojęcia, jak uzyskać dostęp do pobranego pliku. Naprawdę cieszę się, że zadałeś to pytanie jako pierwszy.
Paul D. Waite
AppleScript byłby do tego świetny, gdyby Firefox miał przyzwoity słownik AppleScript.
Nicolas Barbulesco
Czy ktoś może mi pomóc [Pytanie na tej stronie] [1] [1]: stackoverflow.com/questions/27058053/…
Yevgeniy Semashko

Odpowiedzi:

33

Nie żebym o tym wiedział. Możesz jednak skonfigurować Firefoksa, aby automatycznie rozpoczynał pobieranie i zapisywał plik w określonym miejscu. Twój test może wtedy sprawdzić, czy plik faktycznie dotarł.

Aaron Digulla
źródło
Ok, myślę, że wybiorę to rozwiązanie.
Andrey Shchekin
1
Ale selen uruchomi Firefoksa w domyślnym profilu (ponieważ nie określono profilu), więc za każdym razem, gdy go konfigurujesz. Zamiast tego utwórz nowy profil ze swoimi preferencjami, aby było łatwiej.
Vignesh Dhamodaran
71

Mam rozwiązanie tego problemu, sprawdź kod:

FirefoxProfile firefoxProfile = new FirefoxProfile();

firefoxProfile.setPreference("browser.download.folderList",2);
firefoxProfile.setPreference("browser.download.manager.showWhenStarting",false);
firefoxProfile.setPreference("browser.download.dir","c:\\downloads");
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk","text/csv");

WebDriver driver = new FirefoxDriver(firefoxProfile);//new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);

driver.navigate().to("http://www.myfile.com/hey.csv");
dlopezgonzalez
źródło
1
Blisko, ale niezupełnie działa dla Firefoksa na Ubuntu 12.04 od 17.08.2013. Zmień wartość właściwości „browser.helperApps.neverAsk.saveToDisk” na „text / csv, application / vnd.ms-excel” i będzie działać na Ubuntu.
bakoyaro,
2
Może być zmieniona nazwa wartości, od ponad roku.
dlopezgonzalez
1
Używam tej samej metody automatycznego zapisywania pliku, ale nie działa. Moja wersja Firefoksa to 20.0. Próbuję pobrać pliki pdf (używany typ MIME-> application / pdf, application / x-pdf)
Yatin
4
Nie żeby to nie działało Content-Disposition: attachment. Wydaje się, że Firefox zawsze wyskakuje okno dialogowe w tym przypadku!
Martin Höller
do pobierania plików xls w systemie Linux to zadziałało dla mnie:setPreference("browser.helperApps.neverAsk.saveToDisk", "application/xls");
donfuxx
43

Utknąłem z tym samym problemem, ale znalazłem rozwiązanie. Zrobiłem to tak samo jak ten blog .

Oczywiście to była Java, przetłumaczyłem ją na Python:

fp = webdriver.FirefoxProfile()

fp.set_preference("browser.download.folderList",2)
fp.set_preference("browser.download.manager.showWhenStarting",False)
fp.set_preference("browser.download.dir",getcwd())
fp.set_preference("browser.helperApps.neverAsk.saveToDisk","text/csv")

browser = webdriver.Firefox(firefox_profile=fp)

W moim przykładzie był to plik CSV. Ale kiedy potrzebujesz więcej, są przechowywane w pliku~/.mozilla/$USER_PROFILE/mimeTypes.rdf

Akendo
źródło
3
Próbowałem tego, ale wydaje mi się, że to nie działa. Nadal pojawia się okno dialogowe zapisywania pliku.
ealfonso
1
Dzięki, ostatnią preferencją było sprzęgło: "application / pdf"
user2426679
1
Używam tej samej metody automatycznego zapisywania pliku, ale nie działa. Moja wersja Firefoksa to 20.0. Próbuję pobrać pliki pdf (używany typ MIME-> application / pdf, application / x-pdf)
Yatin
1
Dziękuję @Akendo. To działa dla mnie przy użyciu Pythona 3.4.3, selenu-2.52 i Firefoksa 44.
Igor
9

Aplikacje internetowe generują 3 różne typy wyskakujących okienek; mianowicie,

 1| JavaScript PopUps
 2| Browser PopUps
 3| Native OS PopUps [e.g., Windows Popup like Upload/Download]

Ogólnie wyskakujące okienka JavaScript są generowane przez kod aplikacji internetowej. Selenium zapewnia interfejs API do obsługi wyskakujących okienek JavaScript, takich jakAlert .

Ostatecznie najprostszym sposobem zignorowania wyskakujących okienek przeglądarki i pobierania plików jest wykorzystanie profili przeglądarki; Można to zrobić na kilka sposobów:

  • Ręcznie wprowadź zmiany we właściwościach przeglądarki (lub)
  • Dostosuj właściwości przeglądarki za pomocą profilu setPreference

Metoda 1

Zanim zaczniesz pracować z wyskakującymi okienkami w profilach przeglądarki, upewnij się, że domyślne opcje pobierania to Zapisz plik.

(Otwórz przeglądarkę Firefox) Narzędzia> Opcje> Aplikacje

wprowadź opis obrazu tutaj

Metoda 2

Skorzystaj z poniższego fragmentu kodu i edytuj w razie potrzeby.

FirefoxProfile profile = new FirefoxProfile();

String path = "C:\\Test\\";
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.dir", path);
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/msword, application/csv, application/ris, text/csv, image/png, application/pdf, text/html, text/plain, application/zip, application/x-zip, application/x-zip-compressed, application/download, application/octet-stream");
profile.setPreference("browser.download.manager.showWhenStarting", false);
profile.setPreference("browser.download.manager.focusWhenStarting", false);  
profile.setPreference("browser.download.useDownloadDir", true);
profile.setPreference("browser.helperApps.alwaysAsk.force", false);
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.download.manager.closeWhenDone", true);
profile.setPreference("browser.download.manager.showAlertOnComplete", false);
profile.setPreference("browser.download.manager.useWindow", false);
profile.setPreference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", false);
profile.setPreference("pdfjs.disabled", true);
       
driver = new FirefoxDriver(profile);
Prashanth Sams
źródło
4

Większość przeglądarek (w moim przypadku Firefox) domyślnie wybiera przycisk OK. Więc udało mi się to rozwiązać za pomocą następującego kodu. Zasadniczo naciska enter i plik jest pobierany.

Robot robot = new Robot();

// A short pause, just to be sure that OK is selected
Thread.sleep(3000);

robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
shish
źródło
4

Miałem ten sam problem. W naszej aplikacji instancja FireFox została utworzona przez przekazanie DesiredCapabilities w następujący sposób

driver = new FirefoxDriver(capabilities);

Na podstawie sugestii innych wprowadziłem zmiany jako

FirefoxProfile firefoxProfile = new FirefoxProfile();     
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk",
    "application/octet-stream");
driver = new FirefoxDrvier(firefoxProfile);

To służyło celowi, ale niestety moje inne testy automatyzacji zaczęły zawodzić. Powodem było to, że usunąłem wcześniej przekazywane możliwości.

Trochę więcej przeglądania w sieci i znalazłem alternatywny sposób. Możemy ustawić sam profil w żądanych Możliwościach.

Tak wygląda nowy działający kod

DesiredCapabilities capabilities = DesiredCapabilities.firefox();

// add more capabilities as per your need.
FirefoxProfile firefoxProfile = new FirefoxProfile();        
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk",
    "application/octet-stream");

// set the firefoxprofile as a capability
capabilities.setCapability(FirefoxDriver.PROFILE, firefoxProfile);
driver = new FirefoxDriver(capabilities);
Sanjay Bharwani
źródło
3

Nie wiem, ale być może możesz sprawdzić źródło jednego z dodatków do pobierania Firefoksa.

Oto źródło tego, którego używam Download Statusbar .

Nifle
źródło
Dzięki, to bardzo interesujące (ale udowadnia, że ​​albo niemożliwe, albo szalenie trudne, chyba że piszę rozszerzenie z częściami xul).
Andrey Shchekin
3

Miałem ten sam problem, nie chciałem mieć dostępu do Save Dialogue.

Poniższy kod może pomóc:

    FirefoxProfile fp = new FirefoxProfile();
    fp.setPreference("browser.download.folderList",2);
    fp.setPreference("browser.download.manager.showWhenStarting",false);
    fp.setPreference("browser.helperApps.alwaysAsk.force", false);
    // Below you have to set the content-type of downloading file(I have set simple CSV file)
    fp.setPreference("browser.helperApps.neverAsk.saveToDisk","text/csv");

W zależności od typu pobieranego pliku należy określić typy zawartości.

Możesz określić wiele typów treści oddzielonych znakiem „ ;'

na przykład:

    fp.setPreference("browser.helperApps.neverAsk.saveToDisk","text/csv;application/vnd.ms-excel;application/msword");
Pratik Patel
źródło
2

Zamiast uruchamiać natywne okno dialogowe pobierania plików, jak na przykład:

By DOWNLOAD_ANCHOR = By.partialLinkText("download");
driver.findElement(DOWNLOAD_ANCHOR).click();

Zwykle robię to zamiast tego, aby ominąć natywne okno dialogowe Pobieranie plików. W ten sposób działa na WSZYSTKICH przeglądarkach:

String downloadURL = driver.findElement(DOWNLOAD_ANCHOR).getAttribute("href");
File downloadedFile = getFileFromURL(downloadURL);

Wymaga to tylko zaimplementowania metody, getFileFromURLktóra używa Apache HttpClient do pobrania pliku i zwrócenia odwołania do pliku.

Podobnie, jeśli używasz Selenide , działa to w ten sam sposób, używając wbudowanej download()funkcji do obsługi pobierania plików.

djangofan
źródło
To zadziała tylko dla plików połączonych statycznie w html, np. Nie dla pliku generowanego na podstawie postu (lub podobnego) żądania.
Todor Minakov
Tak, przebieg może się różnić. Zwykle będziesz w stanie współpracować ze swoimi programistami, aby dowiedzieć się czegoś w tych marginalnych przypadkach.
djangofan
0

Nie zrozumiałem Twojego celu. Czy chciałeś, aby Twój test automatycznie pobierał plik po wykonaniu testu, jeśli tak, to musisz użyć niestandardowego profilu Firefoksa podczas wykonywania testu.

W profilu niestandardowym po raz pierwszy wykonaj test ręcznie, a jeśli pojawi się okno dialogowe pobierania, ustaw je Zapisz na dysku, a także zaznacz pole wyboru Zawsze wykonuj tę akcję, co zapewni, że plik zostanie automatycznie pobrany przy następnym uruchomieniu testu.


źródło
0

Dodatkowo możesz dodać

      profile.setPreference("browser.download.panel.shown",false);

Aby usunąć listę pobranych plików, która jest wyświetlana domyślnie i zakrywa część strony internetowej.

Moje łączne ustawienia to:

        DesiredCapabilities dc = DesiredCapabilities.firefox();
        dc.merge(capabillities);
        FirefoxProfile profile = new FirefoxProfile();
        profile.setAcceptUntrustedCertificates(true);
        profile.setPreference("browser.download.folderList", 4);
        profile.setPreference("browser.download.dir", TestConstants.downloadDir.getAbsolutePath());
        profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
        profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/msword, application/csv, application/ris, text/csv, data:image/png, image/png, application/pdf, text/html, text/plain, application/zip, application/x-zip, application/x-zip-compressed, application/download, application/octet-stream");
        profile.setPreference("browser.download.manager.showWhenStarting", false);
        profile.setPreference("browser.download.manager.focusWhenStarting", false);
        profile.setPreference("browser.download.useDownloadDir", true);
        profile.setPreference("browser.helperApps.alwaysAsk.force", false);
        profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
        profile.setPreference("browser.download.manager.closeWhenDone", true);
        profile.setPreference("browser.download.manager.showAlertOnComplete", false);
        profile.setPreference("browser.download.manager.useWindow", false);
        profile.setPreference("browser.download.panel.shown",false);
        dc.setCapability(FirefoxDriver.PROFILE, profile);
        this.driver = new FirefoxDriver(dc);
Neil Ellis
źródło
1
Cześć Neil Ellis, Kliknięcie przycisku obrazu „Eksportuj” otwiera wyskakujące okienko. Pobieranie pliku jest uruchamiane z wyskakującego okienka, a wyskakujące okienko jest zamykane. Jeśli to możliwe, poprowadź mnie, jak osiągnąć ciche pobieranie plików w tym scenariuszu?
AVA