Скачивание данных с Yandex.Disk с помощью Python

При работе на Google Colab-е столкнулся с ситуацией, когда потребовалось скачать исходники разработанного модуля с Яндекс Диска (Yandex.Disk) на локальный диск Colab. Регистрация приложения для использования библиотеки YaDisk довольно небыстрая. Но можно сделать, если есть время. Ссылка.

Я пошел альтернативным способом, через выдирание параметров авторизации из опубликованной в Яндекс Диск ссылки. Так гораздо проще для простых реализаций.

При скачивании папки с Яндекс Диска в виде архива нужно извлечь папки. У меня все модули Python в одной папке, поэтому интересовала только корневая.

import zipfile, io, os, sys

#Извлекаем директории из архива
def getZipDirs(zip_f, isRootDirOnly = False, addPath = True):
  dirs = []
  for f in zip_f.namelist():
    zinfo = zip_f.getinfo(f)
    if zinfo.is_dir():
      if isRootDirOnly:     # Only root directories:
        # This is will work in any OS because the zip format specifies a forward slash.
        r_dir = f.split('/')
        r_dir = r_dir[0]
        if r_dir not in dirs:
          dirs.append(r_dir)
      else: # All directories:
          dirs.append(f)
  if addPath:
    for dir in dirs:
      sys.path.append(os.path.abspath('/content/' + dir + "/"))        
  return dirs

У функции скачивания файла с Yandex Disk два параметра:

  • url — путь к файлу или папке (например, https://disk.yandex.ru/d/rVVprjVVV2hS-w)
  • isZip — если передан путь к папке, то True, поскольку её содержимое вернется в Zip архиве. Если скачивание текстового файла, то False.

В этой функции архив сразу распаковывается на диск Colab и прописывается в путях для импортирования модуля.

import requests, sys

#url - путь к файлу или папке
#isZip - если передан путь к папке, то её содержимое вернется в Zip архиве
def loadTextFromYandexDisk(url: str, isZip = False):
  base_url = 'https://cloud-api.yandex.net/v1/disk/public/resources/download?'
  final_url = base_url + urlencode(dict(public_key=url))
  response = requests.get(final_url)
  download_url = response.json()['href']
  download_response = requests.get(download_url)
 
  if isZip:
    zip = zipfile.ZipFile(io.BytesIO(download_response.content))
    dirs = getZipDirs(zip, True)
    zip.extractall("/content/")
  else:  
    download_response.encoding = download_response.apparent_encoding
    return download_response.text 

Не забываем добавлять в начало кода код для автозагрузки модуля при обновлении исходников.

%load_ext autoreload
%autoreload 2 #Reload all modules (except those excluded by %aimport) every time before executing the Python code typed.
Spread the love
Запись опубликована в рубрике IT рецепты. Добавьте в закладки постоянную ссылку.

Обсуждение закрыто.