Скачиваем видео с YouTube с помощью Python, без использования pytube

Попробую сделать этот же трюк на Windows.

Попробовал на Windows. Вот для примера ваша глубина вложенности, плюс рабочий стол: C:\Users\test\Desktop\Мой Python\__Видеокурсы Python\01_Онлайн курс Python для тестировщика\Курс\11 Основы автоматизации тестирования веб-приложений с Selenium WebDriver на Python\1 Практика, пишем простой тест проверки веб-сайта_files.

Все отработало корректно.
 
Попробовал на Windows. Вот для примера ваша глубина вложенности, плюс рабочий стол: C:\Users\test\Desktop\Мой Python\__Видеокурсы Python\01_Онлайн курс Python для тестировщика\Курс\11 Основы автоматизации тестирования веб-приложений с Selenium WebDriver на Python\1 Практика, пишем простой тест проверки веб-сайта_files.

Все отработало корректно.

Для тестирования отсканировал свою директорию с курсами. И все также прошло без ошибок.

Вот, даже список для примера:

1 OSINT Library - 11.80 GiB
2 Безопасность, пентест - 300.25 GiB
3 Боты - 28.28 GiB
4 Веб-разработка - 11.28 GiB
5 Новое видео Ютуб - 25.15 GiB
6 Парсинг - 36.90 GiB
7 Программирование - 168.00 GiB

UPD: Для тестирования взял еще более сложный случай - папку с библиотекой calibre. И снова все без ошибок.
 
Для тестирования отсканировал свою директорию с курсами. И все также прошло без ошибок.

Вот, даже список для примера:

1 OSINT Library - 11.80 GiB
2 Безопасность, пентест - 300.25 GiB
3 Боты - 28.28 GiB
4 Веб-разработка - 11.28 GiB
5 Новое видео Ютуб - 25.15 GiB
6 Парсинг - 36.90 GiB
7 Программирование - 168.00 GiB

UPD: Для тестирования взял еще более сложный случай - папку с библиотекой calibre. И снова все без ошибок.

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

Python:
from os import stat, path, walk, listdir
from pathlib import Path
from sys import exit as ex


def correct_size(bts: int, ending='iB') -> str:
    """
    Корректируется размер файла.
    :param bts: размер файла, целое число.
    :param ending: суффикс, добавляемый к метрике.
    :return: строка, корректированный размер файла.
    """
    size = 1024
    for item in ["", "K", "M", "G", "T", "P"]:
        if bts < size:
            return f"{bts:.2f} {item}{ending}"
        bts /= size


def folder_scan(path_dir: str) -> str:
    """
    Определение размера директории. Сканируется директория.
    Определяется размер каждого файла находящегося в ней.
    Суммируется в общей переменной. После завершения сканирования
    возвращается скорректированный размер.
    :param path_dir: строка, путь к директории для сканирования.
    :return: строка, скорректированный размер файла.
    """
    file_size = stat(path_dir).st_size
    for root, dirs, files in walk(path_dir):
        for file in files:
            file_size = file_size + stat(path.join(root, file)).st_size
    return correct_size(file_size)


def list_dir(path_dir: str):
    """
    Сканирование директории. Определение размера файлов и папок.
    Добавление данных об имени и размере в текстовый документ.
    Сортировка полученных объектов на файлы и папки в процессе
    итерации по ним. Если файл, определяем размер сразу. Если папка,
    передаем путь к ней в функцию получения размера папки.
    :param path_dir: строка, путь к директории для сканирования.
    """
    rez = sorted(listdir(path_dir))
    file_name = f'{Path(path_dir).name}'
    
    with open(f"{file_name}.txt", "w") as file:
        for n, item in enumerate(rez):
            if path.isdir(path.join(path_dir, item)):
                size = folder_scan(path.join(path_dir, item))
            else:
                size = correct_size(stat(path.join(path_dir, item)).st_size)
            file.write(f"{n + 1} {item} - {size}\n")
    print(f'Список файлов смотрим здесь - {file_name}.txt ')


def main():
    """
    Запрос у пользователя пути к сканируемой директории.
    Запуск функции сканирования с передачей в нее
    полученного от пользователя пути.
    """
    path_dir = input("Введите путь к сканируемой директории: ")
    if not path.exists(path_dir):
        print("Введенной вами директории не существует.")
        ex(0)
    list_dir(path_dir)


if __name__ == "__main__":
    main()
 
  • Нравится
Реакции: satfan
Немного изменил код, добавил получение названия сканированной директории, чтобы файл сохранялся с ее именем.

Python:
from os import stat, path, walk, listdir
from pathlib import Path
from sys import exit as ex


def correct_size(bts: int, ending='iB') -> str:
    """
    Корректируется размер файла.
    :param bts: размер файла, целое число.
    :param ending: суффикс, добавляемый к метрике.
    :return: строка, корректированный размер файла.
    """
    size = 1024
    for item in ["", "K", "M", "G", "T", "P"]:
        if bts < size:
            return f"{bts:.2f} {item}{ending}"
        bts /= size


def folder_scan(path_dir: str) -> str:
    """
    Определение размера директории. Сканируется директория.
    Определяется размер каждого файла находящегося в ней.
    Суммируется в общей переменной. После завершения сканирования
    возвращается скорректированный размер.
    :param path_dir: строка, путь к директории для сканирования.
    :return: строка, скорректированный размер файла.
    """
    file_size = stat(path_dir).st_size
    for root, dirs, files in walk(path_dir):
        for file in files:
            file_size = file_size + stat(path.join(root, file)).st_size
    return correct_size(file_size)


def list_dir(path_dir: str):
    """
    Сканирование директории. Определение размера файлов и папок.
    Добавление данных об имени и размере в текстовый документ.
    Сортировка полученных объектов на файлы и папки в процессе
    итерации по ним. Если файл, определяем размер сразу. Если папка,
    передаем путь к ней в функцию получения размера папки.
    :param path_dir: строка, путь к директории для сканирования.
    """
    rez = sorted(listdir(path_dir))
    file_name = f'{Path(path_dir).name}'
  
    with open(f"{file_name}.txt", "w") as file:
        for n, item in enumerate(rez):
            if path.isdir(path.join(path_dir, item)):
                size = folder_scan(path.join(path_dir, item))
            else:
                size = correct_size(stat(path.join(path_dir, item)).st_size)
            file.write(f"{n + 1} {item} - {size}\n")
    print(f'Список файлов смотрим здесь - {file_name}.txt ')


def main():
    """
    Запрос у пользователя пути к сканируемой директории.
    Запуск функции сканирования с передачей в нее
    полученного от пользователя пути.
    """
    path_dir = input("Введите путь к сканируемой директории: ")
    if not path.exists(path_dir):
        print("Введенной вами директории не существует.")
        ex(0)
    list_dir(path_dir)


if __name__ == "__main__":
    main()
Опять ошибк:
Введите путь к сканируемой директории: E:\Мой Python\__Видеокурсы Python
Traceback (most recent call last):
File "E:\__Moi_scripti\10_files in a directory\11.py", line 72, in <module>
main()
File "E:\__Moi_scripti\10_files in a directory\11.py", line 68, in main
list_dir(path_dir)
File "E:\__Moi_scripti\10_files in a directory\11.py", line 51, in list_dir
size = folder_scan(path.join(path_dir, item))
File "E:\__Moi_scripti\10_files in a directory\11.py", line 32, in folder_scan
file_size = file_size + stat(path.join(root, file)).st_size
FileNotFoundError: [WinError 3] Системе не удается найти указанный путь: 'E:\\Мой Python\\__Видеокурсы Python\\01_Онлайн курс Python для тестировщика\\Курс\\11 Основы автоматизации тестирования веб-приложений с Selenium WebDriver на Python\\1 Практика, пишем простой тест проверки веб-сайта_files\\488c2a4e544f5d0cea166cfb9e33153247829078.jpg'
 
Опять ошибк:
Введите путь к сканируемой директории: E:\Мой Python\__Видеокурсы Python
Traceback (most recent call last):
File "E:\__Moi_scripti\10_files in a directory\11.py", line 72, in <module>
main()
File "E:\__Moi_scripti\10_files in a directory\11.py", line 68, in main
list_dir(path_dir)
File "E:\__Moi_scripti\10_files in a directory\11.py", line 51, in list_dir
size = folder_scan(path.join(path_dir, item))
File "E:\__Moi_scripti\10_files in a directory\11.py", line 32, in folder_scan
file_size = file_size + stat(path.join(root, file)).st_size
FileNotFoundError: [WinError 3] Системе не удается найти указанный путь: 'E:\\Мой Python\\__Видеокурсы Python\\01_Онлайн курс Python для тестировщика\\Курс\\11 Основы автоматизации тестирования веб-приложений с Selenium WebDriver на Python\\1 Практика, пишем простой тест проверки веб-сайта_files\\488c2a4e544f5d0cea166cfb9e33153247829078.jpg'
Спасибо. Изменил путь к папке всё сработало.
 
Спасибо. Изменил путь к папке всё сработало.

Кстати, да. Сразу же не обратил внимания. Уже привык к тому, что в Linux все ОК.
Путь path = 'E:\Мой Python\__Видеокурсы Python' нужно либо экранировать, либо поставить букву r, чтобы не обрабатывались обратные слеши.
то есть, path = r'E:\Мой Python\__Видеокурсы Python'. Это в том случае, если не передавать путь к папке с помощью input, а передавать в коде.
 
Кстати, да. Сразу же не обратил внимания. Уже привык к тому, что в Linux все ОК.
Путь path = 'E:\Мой Python\__Видеокурсы Python' нужно либо экранировать, либо поставить букву r, чтобы не обрабатывались обратные слеши.
то есть, path = r'E:\Мой Python\__Видеокурсы Python'. Это в том случае, если не передавать путь к папке с помощью input, а передавать в коде.
Спасибо. В моём исходном скрипте всё прввильно.
А в Вашем крайнем как применить это правило ?
 
В моем никак. Если путь передается с помощью ввода, он автоматом попадает в path уже в нужном виде.
Спасибо. Вы отлично разбираетесь в питоне. Мне тоже Вам хочется быть полезным.
У меня хобби: Спутниковое ТВ и IPTV. Может вам нужны какие плейлисты m3u (Их читает : PotPlayer и VLC плеер)
 
Спасибо. Вы отлично разбираетесь в питоне. Мне тоже Вам хочется быть полезным.
У меня хобби: Спутниковое ТВ и IPTV. Может вам нужны какие плейлисты m3u (Их читает : PotPlayer и VLC плеер)
Ещё у меня проблемка.
Скрипт не срабатывает - 18_Поиск текста в файлах папки:
Python:
# -*- coding: utf-8 -*
import glob

dirname = r'C:\Users\Пк\Desktop\1_Изучаем Python'
line = 'Яндекс Лицей'

for name in glob.glob(f"{dirname}/**/*.m3u"):
    file_info = open(name, mode="r", encoding='utf-8').read()
    if line in fileinfo:
        print(f'Нашел нужную строчку в файле {name}')

# 1_Изучаем Python  - это моя папка
# C:\Users\Пк\Desktop\1_Изучаем Python - это путь к папке
# Яндекс Лицей - это ищем в файлах с расширением .m3u
 
Ещё у меня проблемка.
Скрипт не срабатывает - 18_Поиск текста в файлах папки:
Python:
# -*- coding: utf-8 -*
import glob

dirname = r'C:\Users\Пк\Desktop\1_Изучаем Python'
line = 'Яндекс Лицей'

for name in glob.glob(f"{dirname}/**/*.m3u"):
    file_info = open(name, mode="r", encoding='utf-8').read()
    if line in fileinfo:
        print(f'Нашел нужную строчку в файле {name}')

# 1_Изучаем Python  - это моя папка
# C:\Users\Пк\Desktop\1_Изучаем Python - это путь к папке
# Яндекс Лицей - это ищем в файлах с расширением .m3u

Скиньте мне один или несколько плейлистов в личку. Чуть позже посмотрю. Сейчас немного занят.
 
В личном сообщении на форуме. Запакуй несколько плейлистов в архив и прикрепи к сообщению во вложении. Плейлисты много места не занимают.
Папка путь: C:\Users\Пк\Desktop\2_Мои IPTV
Изменил расширение файла: m3u на txt --- иначе не смог загрузить сюда форум.
Моя почта: mav53@bk.ru
 

Вложения

Последнее редактирование:
Ещё у меня проблемка.
Скрипт не срабатывает - 18_Поиск текста в файлах папки:
Python:
# -*- coding: utf-8 -*
import glob

dirname = r'C:\Users\Пк\Desktop\1_Изучаем Python'
line = 'Яндекс Лицей'

for name in glob.glob(f"{dirname}/**/*.m3u"):
    file_info = open(name, mode="r", encoding='utf-8').read()
    if line in fileinfo:
        print(f'Нашел нужную строчку в файле {name}')

# 1_Изучаем Python  - это моя папка
# C:\Users\Пк\Desktop\1_Изучаем Python - это путь к папке
# Яндекс Лицей - это ищем в файлах с расширением .m3u

В данном коде присутствует не одна проблема, а сразу же несколько. Но об этом по порядку.
Итак, первая проблема, это с путями. Нужно запомнить, что в ОС Windows пути указываются через обратный слеш «\», а в ОС Linux через прямой «/».
В твоем коде ты указываешь путь к директории правильно, для ОС Windows, а вот уже путь к искомому файлу у тебя указан странно:

glob.glob(f"{dirname}/**/*.m3u")

Такое указание путей для Windows не подойдет.

Двигаемся дальше. Если указать тот путь, без дополнительных параметров, будут просканированы директории только на один уровень вниз. Предположим, что у тебя структура файлов как на картинке ниже:

01.png


Тогда директории, которые указаны стрелками будут просканированы. А вот сама директория «Курсы», в которой тоже могут находиться файлы и субдиректория «2_Изучаем Python», на картинке они выделены желтым, просканированы уже не будут. «Курсы» потому, что не попадают в путь твоего шаблона, а «2_Изучаем Python» просто находиться глубже, чем путь в шаблоне. Соответственно, будет выполнен только частичный поиск.

Для того, чтобы поиск был рекурсивным, то есть обходил все папки, нужно параметр glob — recursive, установить в значение True.

Теперь по поводу путей. Если ты хочешь, чтобы поиск файлов проходил вне зависимости от того, на какой ОС ты используешь данный код, то желательно и пути указывать не в «жестком» варианте, а с помощью модуля os.path.join или использовать Path из библиотеки pathlib. Разница будет не особо великая. Можно использовать как тот, так и другой вариант.

Еще одна недоработка заключается в том, что ты пытаешься искать слово или словосочетание в полном файле. Так делать можно, если для тебя не принципиально, сколько совпадений в файле, и в какой именно стороке они найдены. В варианте поиска вхождения в полном файле будет просто обозачено, что да, такое совпадение есть.

Но, если ты хочешь узнать, сколько вхождений в файле и в какой строке, лучше читать файл построчно в цикле. То есть, использовать не read(), а readlines().

Таким образом, если искать по всему файлу целиком, код будет таким:

Python:
import sys
from glob import glob
from pathlib import Path


def scan(path_dir: str, req: str):
    """
    Выполняется итерация по каталогам(рекурсивно) и ищется
    файл по заданному шаблону. После того как файл найден,
    он открывается для чтения.
    Выполняется условие, по поиску вхождения в текст файла.
    Если найден, печатаем где. Если нет, двигаемся дальше.

    :param path_dir: строка, путь к директории для сканирования.
    :param req: строка, слово или предложение, вхождение которого нужно найти.
    """
    try:
        print("")
        for name in glob(str(Path(path_dir) / "**" / "*.m3u"), recursive=True):
            with open(name, "r", encoding='utf-8') as resp:
                if req in resp.read():
                    print(f"Найдено совпадение в файле: {name}")
    except KeyboardInterrupt:
        print("\nGood By!")


def main():
    try:
        path_dir = input("Введите путь к директории для сканирования: ")
        req = input("Введите искомое слово или словосочетание: ")
        if not Path(path_dir).exists():
            print("Введенного пути не существует!")
            sys.exit(0)
        scan(path_dir=path_dir, req=req)
    except KeyboardInterrupt:
        print("\nGood By!")


if __name__ == "__main__":
    main()

Ну, а если искать сколько вхождений и в какой строке, то таким:

Python:
import sys
from glob import glob
from pathlib import Path


def scan(path_dir: str, req: str):
    """
    Выполняется итерация по каталогам(рекурсивно) и ищется
    файл по заданному шаблону. После того как файл найден,
    он открывается для чтения построчно. В цикле выполняется
    итерация по каждой строке, и проверяется вхождение
    искомого слова или предложения.
    Если вхождение найдено, добавляем строку с номером и текстом
    во временный список.
    После того как цикл завершиться, проверяем какова длина
    списка. Если она больше нуля, печатаем сколько совпадений
    и выводим каждую строку, в которой найдено совпадение.

    :param path_dir: строка, путь к директории для сканирования.
    :param req: строка, слово или предложение, вхождение которого нужно найти.
    """
    try:
        for name in glob(str(Path(path_dir) / "**" / "*.m3u"), recursive=True):
            lines = []
            with open(name, "r", encoding='utf-8') as resp:
                for n, line in enumerate(resp.readlines()):
                    if req in line:
                        lines.append(f"Строка: {n+1}, {line.strip()}")
                if len(lines) > 0:
                    print(f'\n[+] Совпадений: {len(lines)}, в файле: {name}')
                    for ln in lines:
                        print(f"   - {ln}")
    except KeyboardInterrupt:
        print("\nGood By!")


def main():
    try:
        path_dir = input("Введите путь к директории для сканирования: ")
        req = input("Введите искомое слово или словосочетание: ")
        if not Path(path_dir).exists():
            print("Введенного пути не существует!")
            sys.exit(0)
        scan(path_dir=path_dir, req=req)
    except KeyboardInterrupt:
        print("\nGood By!")


if __name__ == "__main__":
    main()

Ну и соответственно, в первом случае вывод будет такой:

02.png


Во-втором, такой:

03.png


Такие вот дела.
 
  • Нравится
Реакции: satfan
В данном коде присутствует не одна проблема, а сразу же несколько. Но об этом по порядку.
Итак, первая проблема, это с путями. Нужно запомнить, что в ОС Windows пути указываются через обратный слеш «\», а в ОС Linux через прямой «/».
В твоем коде ты указываешь путь к директории правильно, для ОС Windows, а вот уже путь к искомому файлу у тебя указан странно:

glob.glob(f"{dirname}/**/*.m3u")

Такое указание путей для Windows не подойдет.

Двигаемся дальше. Если указать тот путь, без дополнительных параметров, будут просканированы директории только на один уровень вниз. Предположим, что у тебя структура файлов как на картинке ниже:

Посмотреть вложение 64489

Тогда директории, которые указаны стрелками будут просканированы. А вот сама директория «Курсы», в которой тоже могут находиться файлы и субдиректория «2_Изучаем Python», на картинке они выделены желтым, просканированы уже не будут. «Курсы» потому, что не попадают в путь твоего шаблона, а «2_Изучаем Python» просто находиться глубже, чем путь в шаблоне. Соответственно, будет выполнен только частичный поиск.

Для того, чтобы поиск был рекурсивным, то есть обходил все папки, нужно параметр glob — recursive, установить в значение True.

Теперь по поводу путей. Если ты хочешь, чтобы поиск файлов проходил вне зависимости от того, на какой ОС ты используешь данный код, то желательно и пути указывать не в «жестком» варианте, а с помощью модуля os.path.join или использовать Path из библиотеки pathlib. Разница будет не особо великая. Можно использовать как тот, так и другой вариант.

Еще одна недоработка заключается в том, что ты пытаешься искать слово или словосочетание в полном файле. Так делать можно, если для тебя не принципиально, сколько совпадений в файле, и в какой именно стороке они найдены. В варианте поиска вхождения в полном файле будет просто обозачено, что да, такое совпадение есть.

Но, если ты хочешь узнать, сколько вхождений в файле и в какой строке, лучше читать файл построчно в цикле. То есть, использовать не read(), а readlines().

Таким образом, если искать по всему файлу целиком, код будет таким:

Python:
import sys
from glob import glob
from pathlib import Path


def scan(path_dir: str, req: str):
    """
    Выполняется итерация по каталогам(рекурсивно) и ищется
    файл по заданному шаблону. После того как файл найден,
    он открывается для чтения.
    Выполняется условие, по поиску вхождения в текст файла.
    Если найден, печатаем где. Если нет, двигаемся дальше.

    :param path_dir: строка, путь к директории для сканирования.
    :param req: строка, слово или предложение, вхождение которого нужно найти.
    """
    try:
        print("")
        for name in glob(str(Path(path_dir) / "**" / "*.m3u"), recursive=True):
            with open(name, "r", encoding='utf-8') as resp:
                if req in resp.read():
                    print(f"Найдено совпадение в файле: {name}")
    except KeyboardInterrupt:
        print("\nGood By!")


def main():
    try:
        path_dir = input("Введите путь к директории для сканирования: ")
        req = input("Введите искомое слово или словосочетание: ")
        if not Path(path_dir).exists():
            print("Введенного пути не существует!")
            sys.exit(0)
        scan(path_dir=path_dir, req=req)
    except KeyboardInterrupt:
        print("\nGood By!")


if __name__ == "__main__":
    main()

Ну, а если искать сколько вхождений и в какой строке, то таким:

Python:
import sys
from glob import glob
from pathlib import Path


def scan(path_dir: str, req: str):
    """
    Выполняется итерация по каталогам(рекурсивно) и ищется
    файл по заданному шаблону. После того как файл найден,
    он открывается для чтения построчно. В цикле выполняется
    итерация по каждой строке, и проверяется вхождение
    искомого слова или предложения.
    Если вхождение найдено, добавляем строку с номером и текстом
    во временный список.
    После того как цикл завершиться, проверяем какова длина
    списка. Если она больше нуля, печатаем сколько совпадений
    и выводим каждую строку, в которой найдено совпадение.

    :param path_dir: строка, путь к директории для сканирования.
    :param req: строка, слово или предложение, вхождение которого нужно найти.
    """
    try:
        for name in glob(str(Path(path_dir) / "**" / "*.m3u"), recursive=True):
            lines = []
            with open(name, "r", encoding='utf-8') as resp:
                for n, line in enumerate(resp.readlines()):
                    if req in line:
                        lines.append(f"Строка: {n+1}, {line.strip()}")
                if len(lines) > 0:
                    print(f'\n[+] Совпадений: {len(lines)}, в файле: {name}')
                    for ln in lines:
                        print(f"   - {ln}")
    except KeyboardInterrupt:
        print("\nGood By!")


def main():
    try:
        path_dir = input("Введите путь к директории для сканирования: ")
        req = input("Введите искомое слово или словосочетание: ")
        if not Path(path_dir).exists():
            print("Введенного пути не существует!")
            sys.exit(0)
        scan(path_dir=path_dir, req=req)
    except KeyboardInterrupt:
        print("\nGood By!")


if __name__ == "__main__":
    main()

Ну и соответственно, в первом случае вывод будет такой:

Посмотреть вложение 64490

Во-втором, такой:

Посмотреть вложение 64491

Такие вот дела.
Спасибо огромное. Вы мне целую лекция прочитали. Всё отлично работает. Впервые получаю такю грамотную поддержку.
 
Спасибо автору за работу. Всё работает из коробки, без проблем, а значит написано грамотно и с душой)
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!