Статья Пишем простой менеджер загрузок

Tayrus

Tayrus

Grey Team
13.04.2017
360
731
Приветствую всех, эта рубрика моих никому не нужных разработок. И сегодня мы с вами будем писать простой менеджер загрузок или сценарий для загрузки больше кол-ва файлов. Попробую объяснить для чего это. Представьте что у вас есть ссылки на загрузку музыки(их очень много), вы же не будете переходить по каждой ссылке и скачивать? Мы автоматизируем этот процесс. В файле будут ссылки на скачку, а сценарий скачает их за нас.

!Пишу на python3!
Идея статьи в том, чтобы улучшить знания python читателя(возможно он откроет для себя что-то новое).
Вот такие либы я буду юзать для реализации того, что я хочу.
Код:
import requests
import random
import glob
import os
import shutil
Введем списки для работы:
Код:
site = []
files = []
Теперь реализуем чтение ссылок из файла:
Код:
handle = open('sites.txt') # Читаем файл
for x in handle: #Записуем содержимое файла в список
    site.append(x)
site = map(lambda s: s.strip(), site) # Удаляем из списка \n
site = list(site) # Конвертим в тип list(список)
Теперь напишем загрузку файлов:
Код:
for x in site:
    if x == '': # Если будет пустой элемент пропустить
        continue
    ran = random.randint(1,999999) # Рандомное число в переменную присваем

    handle = open(str(ran) + '.unknow',"wb") # Открываем на запись файл с именем(рандомное число) и форматом .unknown
    ufr = requests.get(x)
    handle.write(ufr.content) # Скачиваем и записуем содержимое файла
    handle.close()
Так как скачанные файлы имеют формат .unknown, возможно пользователь захочет изменить формат файлов, тк.к может он скачивал .mp3:
Код:
formats = input("На какой формат изменить скачанные файлы? => ")
Теперь в текущей директории мы будем искать файлы формата .unknown:
Код:
for file in glob.glob("*.unknow"):
    files.append(file)
Теперь будем менять .unknown на формат, который указал пользователь:
Код:
for x in files:
    ran = random.randint(1,999999)
    shutil.copy(x, str(ran) + '.' + formats)
Удаляем .unkown файлы:
Код:
for x in files:
    os.remove(x)
И будем печатать, что все успешно:
Код:
print ('done')
Весь код:
Код:
import requests
import random
import glob
import os
import shutil

site = []
files = []

handle = open('sites.txt')
for x in handle:
    site.append(x)
site = map(lambda s: s.strip(), site)
site = list(site)



for x in site:
    if x == '':
        continue
    ran = random.randint(1,999999)

    handle = open(str(ran) + '.unknow',"wb")
    ufr = requests.get(x)
    handle.write(ufr.content)
    handle.close()

formats = input("На какой формат изменить скачанные файлы? => ")

for file in glob.glob("*.unknow"):
    files.append(file)

for x in files:
    ran = random.randint(1,999999)
    shutil.copy(x, str(ran) + '.' + formats)

for x in files:
    os.remove(x)

print ('done')
В sites.txt должны быть прямые ссылки, вот пример:
Код:
https://api.soundcloud.com/tracks/450378462/stream?client_id=7UodytM4nnvd8JmPdgaMgcu2DYGdiZrT
https://api.soundcloud.com/tracks/450379818/stream?client_id=7UodytM4nnvd8JmPdgaMgcu2DYGdiZrT
Спасибо за внимание!
 
Последнее редактирование:
Dwight Schrute

Dwight Schrute

Member
18.01.2018
7
23
Привет, позволь провести code review.

  • В Python, если ты пишешь исполняемый скрипт, то принято использовать конструкцию
Python:
def main():
    pass


if __name__ == "__main__":
    main()
В таком случае, при импорте из другого скрипта, код не будет выполнен автоматически.
  • Для управления поведением программы, можно использовать модуль argparse. Например, чтобы передавать путь к файлу с URL'ами или интересующему расширению файлов. В данном случае, использование input не оправдано.
  • Поднимать в память все содержимое файла, плохая идея. Если размер файла будет несколько гигабайт или террабайт, то тебе не хватит RAM. Лучше всего читать файл построчно и отдавать за одну итерацию, только одну строку. Для этой задачи отлично подойдет использование генераторов.
Python:
def read_file(file_path):
  with open(file_path, "r") as f:
    for line in f:
      yield line.strip()


for line in read_file("111.txt"):
  print(line)
  • Далее
Python:
for x in site:
    if x == '':
        continue
    ran = random.randint(1,999999)

    handle = open(str(ran) + '.unknow',"wb")
    ufr = requests.get(x)
    handle.write(ufr.content)
    handle.close()
1)
Python:
for x in site
, лучше выбирать более осмысленные названия для переменных, так как если тело цикла получится достаточно большим и сложным, то далее по коду будет тяжело вспомнить, что это за X? Лучше писать так:
Python:
for site in sites
2) Проверку на пустую строку лучше делать так:
Python:
if not x:
    continue
3) Для генерации имен файлов, имеет смысл просто считать md5 hash от URL'a
Python:
import hashlib
file_name = hashlib.md5(x.encode('utf-8')).hexdigest()
4)
Python:
handle = open(str(ran) + '.unknow',"wb")
- сначала создается файл, а потом начинается закачка. Если requests бросит исключение, то ты у тебя будет создан пустой файл.
5) Для открытия файла, лучше использовать менеджер контекста with, тогда не придется заботить о закрытии файла.

Python:
formats = input("На какой формат изменить скачанные файлы? => ")

for file in glob.glob("*.unknow"):
    files.append(file)

for x in files:
    ran = random.randint(1,999999)
    shutil.copy(x, str(ran) + '.' + formats)

for x in files:
    os.remove(x)
Вместо копирования и удаления файлов, можно просто их переименовывать с помощью os.rename()
 
darklight

darklight

Well-known member
18.10.2018
46
60
так и не понял, зачем менять названия и расширения файлов, а потом их переименовывать вручную если предполагается массовая загрузка
 
Мы в соцсетях:  ТелеграмВконтактеДзенФейсбукТвиттерЮтуб