2012-01-09 1 views
0

Мне нужно загрузить файл в заданное место на нелокальной машине. Это нормальный поток веб-браузер, для которого я хотел бы сделать это:Загрузите файл по определенному пути, используя Selenium WebDriver

  • Перейти на сайт
  • Нажмите на кнопку, чтобы загрузить файл (это форма, которая создает файл, не ссылку скачать)
  • сайт запрашивает окно предупреждения «вы хотите, чтобы загрузить этот файл?» и т.д.

Я хочу, чтобы иметь возможность обойти этот файл и сделать что-то вроде:

>>> path_to_download_path = PATH 
>>> button = driver.find_element_by_css("...") 
>>> button.click() 

--> And the file is automatically downloaded to my PATH (or wherever I choose) 

Или есть более простой способ, который click, где я могу автоматически загружать содержимое файла?

Как мне это сделать?

+0

Я думаю, что вы можете только установить путь загрузки, если есть поле ввода или что-то подобное, где вы можете установить путь - WebDriver может взаимодействовать только с элементами, которые пользователь может увидеть на сайте – chaosr

+0

может помочь знать, какой браузер вы управляете, поскольку они, как правило, обрабатывают загрузки файлов по-разному –

ответ

1

Вам нужно будет изучить javascript на веб-сайте и понять, как он работает, прежде чем вы сможете переопределить его, чтобы сделать что-то подобное, но даже тогда безопасность браузера всегда будет появляться в диалоговом окне с просьбой подтвердить загрузку. Это оставляет вас с двумя вариантами (насколько я могу видеть):

  • Подтвердить предупреждение диалог
  • определить местоположение файла на удаленном сервере, и использовать GET для загрузки файла

Я не могу помочь с деталями на любой, так как я не знаю, питона, но, надеюсь, что помогает ...

0

Использование селеном WebDriver

Использование светлячок Prof для загрузки файлов. Этот профиль пропускает это диалоговое окно firefox. В строке: -

pro.setPreference("browser.downLoad.folderList", 0); 

Значение browser.download.folderList может быть установлен либо 0, 1 или 2. Если установлено значение 0, Firefox сохранит все файлы, загруженные с помощью браузера на компьютере пользователя , Если установлено значение 1, эти загрузки хранятся в папке «Загрузки». Когда установлено значение 2, местоположение, указанное для самой последней загрузки, используется снова.

Firefox профиль код, который нужен реализовать: -

 FirefoxProfile pro=new FirefoxProfile(); 
     pro.setPreference("browser.downLoad.folderList", 0); 
     pro.setPreference("browser.helperApps.neverAsk.saveToDisk", "Applications/zip"); 
     WebDriver driver=new FirefoxDriver(pro); 
     driver.get("http://selenium-release.storage.googleapis.com/2.47/selenium-java-2.47.1.zip"); 

Надеется, что это поможет :)

0

При инициализации драйвера, не забудьте установить загрузку настройки.

Для Firefox:

ff_prof.set_preference("browser.download.manager.showWhenStarting", False) 
ff_prof.set_preference("browser.download.folderList", 2) 
ff_prof.set_preference("browser.download.useDownloadDir", True) 
ff_prof.set_preference("browser.download.dir", self.driver_settings['download_folder']) 

## 
# if FF still shows the download dialog, make sure that the filetype is included below 
# filetype string options can be found in '~/.mozilla/$USER_PROFILE/mimeTypes.rdf' 
## 
mime_types = ("application/pdf", "text/html") 

ff_prof.set_preference("browser.helperApps.neverAsk.saveToDisk", (", ".join(mime_types))) 
ff_prof.set_preference("browser.helperApps.neverAsk.openFile", (", ".join(mime_types))) 

Для Chrome:

capabilities['chromeOptions']['prefs']['download.prompt_for_download'] = False 
capabilities['chromeOptions']['prefs']['download.default_directory'] = self.driver_settings['download_folder'] 

Forwarding загрузки:

Ниже приведен код, который я использую для перенаправления файла с self.driver_settings['download_folder'] (устанавливается выше), где вы действительно хотите, чтобы файл (to_path мог быть существующей папкой или файловым путем). Если вы используете linux, я бы предложил использовать tmpfs, чтобы /tmp был помещен в плунжер, а затем установил self.driver_settings['download_folder'] в "/tmp/driver_downloads/". Обратите внимание, что в приведенной ниже функции предполагается, что self.driver_settings['download_folder'] всегда начинается как пустая папка (так он находит загружаемый файл, так как он единственный в каталоге).

def moveDriverDownload(self, to_path, allowable_extensions, allow_rename_if_exists=False, timeout_seconds=None): 
    if timeout_seconds is None: 
     timeout_seconds = 30 
    wait_delta = timedelta(seconds=timeout_seconds) 
    start_download_time = datetime.now() 
    hasTimedOut = lambda: datetime.now() - start_download_time > wait_delta 

    assert isinstance(allowable_extensions, list) or isinstance(allowable_extensions, tuple) or isinstance(allowable_extensions, set), "instead of a list, found allowable_extensions type of '{}'".format(type(allowable_extensions)) 
    allowable_extensions = [ elem.lower().strip() for elem in allowable_extensions ] 
    allowable_extensions = [ elem if elem.startswith(".") else "."+elem for elem in allowable_extensions ] 

    if not ".part" in allowable_extensions: 
     allowable_extensions.append(".part") 

    re_extension_str = "(?:" + ("$)|(?:".join(re.escape(elem) for elem in allowable_extensions)) + "$)" 

    getFiles = lambda: next(os.walk(self.driver_settings['download_folder']))[2] 

    while True: 
     if hasTimedOut(): 
      del allowable_extensions[ allowable_extensions.index(".part") ] 
      raise DownloadTimeoutError("timed out after {} seconds while waiting on file download with extension in {}".format(timeout_seconds, allowable_extensions)) 

     time.sleep(0.5) 

     file_list = [ elem for elem in getFiles() if re.search(re_extension_str, elem) ] 
     if len(file_list) > 0: 
      break 

    file_list = [ re.search(r"(?i)^(.*?)(?:\.part)?$", elem).groups()[0] for elem in file_list ] 

    if len(file_list) > 1: 
     if len(file_list) == 2: 
      if file_list[0] != file_list[1]: 
       raise Exception("file_list[0] != file_list[1] <==> {} != {}".format(file_list[0], file_list[1])) 
     else: 
      raise Exception("len(file_list) > 1. found {}".format(file_list)) 

    file_path = "%s%s" %(self.driver_settings['download_folder'], file_list[0]) 

    # see if the file is still being downloaded by checking if it's open by any programs 
    if platform.system() == "Linux": 
     openProcess = lambda: subprocess.Popen('lsof | grep "%s"' %file_path, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) 
     fileIsFinished = lambda txt: txt.strip() == "" 
    elif platform.system() == "Windows": 
     # 'handle' program must be in PATH 
     # https://technet.microsoft.com/en-us/sysinternals/bb896655 
     openProcess = lambda: subprocess.Popen('handle "%s"' %file_path.replace("/", "\\"), shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) 
     fileIsFinished = lambda txt: bool(re.search("(?i)No matching handles found", txt)) 
    else: 
     raise Exception("unrecognised platform.system() of '{}'".format(platform.system())) 

    while True: 
     lsof_process = openProcess() 
     lsof_result = lsof_process.communicate() 

     if len(lsof_result) != 2: 
      raise Exception("len(lsof_result) != 2. found {}".format(lsof_result)) 
     if lsof_result[1].strip() != "": 
      raise Exception('lsof_result[1].strip() != "". found {}'.format(lsof_result)) 
     if fileIsFinished(lsof_result[0]): 
      break 

     if hasTimedOut(): 
      raise Exception("timed out after {} seconds waiting for '{}' to be freed from writing. found lsof/handle of '{}'".format(timeout_seconds, file_path, lsof_result[0])) 

     time.sleep(0.5) 

    to_path = to_path.replace("\\", "/") 
    if os.path.isdir(to_path): 
     if not to_path.endswith("/"): 
      to_path += "/" 

     to_path += file_list[0] 

    i = 2 
    while os.path.exists(to_path): 
     if not allow_rename_if_exists: 
      raise Exception("{} already exists".format(to_path)) 

     to_path = re.sub("^(.*/)(.*?)(?:-" + str(i-1) + r")?(|\..*?)?$", r"\1\2-%i\3" %i, to_path) 
     i += 1 

    shutil.move(file_path, to_path) 

    return to_path[ to_path.rindex("/")+1: ] 
Смежные вопросы