Задать вопрос
@artyom7777

Как сделать скачивание файла с github релиза на python?

я пытался скачать файл со свойго репозитория на гитхабе, https://github.com/artyom7774/Game-Engine-3/releas..., загружая с него source code с помощью функции на python всё нормально, а когда я пытался загрузить zip архив который закинул в этот релиз скачиваеться 183 кб и останавливаеться, помогите пожалуйста
def versionDownload(url, folder, chunk_size=8192):
    if not os.path.exists(folder):
        os.mkdir(folder)

    with requests.get(url, stream=True) as r:
        r.raise_for_status()
        with open(f"{folder}/engine.zip", 'wb') as f:
            for chunk in r.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)
  • Вопрос задан
  • 119 просмотров
Подписаться 1 Простой 7 комментариев
Пригласить эксперта
Ответы на вопрос 1
@eminsk
developer python, javascripts
Проблема в том, что GitHub автоматически перенаправляет запросы к файлам в релизах, а библиотека requests по умолчанию не следует перенаправлениям при использовании stream=True. Также GitHub требует правильные заголовки для скачивания файлов.

Данный код корректно все нормально делает без ошибок и скачивает в папку где запущен мой скрипт.
если папка download нету она создается автоматически.
А также сделал со всеми проверками в коде
Установи не забудь только requests
import os
import requests
from urllib.parse import urlparse

def versionDownload(url, folder, chunk_size=8192):
    if not os.path.exists(folder):
        os.makedirs(folder, exist_ok=True)
    
    if "github.com" in url and "/releases/" in url and "/download/" not in url:
        print("Обнаружена ссылка на страницу релиза. Попытка найти правильную ссылку...")
        page_response = requests.get(url)
        page_response.raise_for_status()
        
        import re
        download_links = re.findall(r'href="([^"]*\/download\/[^"]*)"', page_response.text)
        
        if download_links:
            url = "https://github.com" + download_links[0] if download_links[0].startswith('/') else download_links[0]
            print(f"Найдена ссылка для скачивания: {url}")
        else:
            print("Не удалось найти файлы для скачивания на странице релиза")
            return None
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Accept': 'application/octet-stream'
    }
    
    print(f"Начался процесс скачивания с URL: {url}")
    
    with requests.get(url, headers=headers, stream=True, allow_redirects=True) as r:
        r.raise_for_status()
        
        content_type = r.headers.get('Content-Type', '')
        if 'text/html' in content_type:
            print("Ошибка: получен HTML вместо файла!")
            print(f"Content-Type: {content_type}")
            print("Проверьте правильность URL")
            return None
        
        filename = "engine.zip"
        if 'Content-Disposition' in r.headers:
            content_disp = r.headers['Content-Disposition']
            if 'filename=' in content_disp:
                filename = content_disp.split('filename=')[1].strip('"')
        else:
            parsed_url = urlparse(url)
            if parsed_url.path:
                filename = os.path.basename(parsed_url.path) or "engine.zip"
        
        file_path = os.path.join(folder, filename)
        
        total_size = int(r.headers.get('Content-Length', 0))
        downloaded_size = 0
        
        print(f"Скачивание {filename}...")
        if total_size > 0:
            print(f"Размер файла: {total_size / (1024*1024):.2f} MB")
        
        with open(file_path, 'wb') as f:
            for chunk in r.iter_content(chunk_size=chunk_size):
                if chunk:
                    f.write(chunk)
                    downloaded_size += len(chunk)
                    
                    if total_size > 0:
                        progress = (downloaded_size / total_size) * 100
                        print(f"\rПрогресс: {progress:.1f}% ({downloaded_size / (1024*1024):.2f} MB)", end='', flush=True)
        
        print(f"\nФайл успешно скачан: {file_path}")
        return file_path

if __name__ == "__main__":
    url = "https://github.com/artyom7774/Game-Engine-3/releases/download/GE3.12.0/Game-Engine-3-windows.sfx.exe"
    versionDownload(url, "./downloads")
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы