[Python] WS Downloader: ¡Descarga vídeos de YouTube!

Iniciado por .:WindHack:., 18 Noviembre 2010, 15:29 PM

0 Miembros y 1 Visitante están viendo este tema.

.:WindHack:.

Código (python) [Seleccionar]
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# WS Downloader.py - v0.1 (Beta)
# Autor(es): .:WindHack:. & swik
# www.daw-labs.com | www.cibernodo.net
# Registrado en SafeCreative
# Licencia: Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0
# 17/11/2010

import sys, urllib, os

#
# @Charset
#
Char = ['%3A','%2F','%26','%2C','%3D','%252C','%253A','%7C','%3F']
By =   [':','/','&',',','=',',',':','<begin>','?']

#
# URLDecode(sURL)
# Descifra la URL teniendo en cuenta el Charset.
#
def URLDecode(sURL):
   for i in range(len(Char)):
    sURL = sURL.replace(Char[i],By[i])
   return sURL

#
# GetSourceCode(sURL)
# Obtiene el código de fuente del vídeo (sitio).
#
def GetSourceCode(sURL):
   try:
    URL = urllib.urlopen(sURL)
    sSource = URL.read()
    URL.close()
    return sSource
   except:
       print 'Error de conexión.'
       exit()

#
# GetIndexVideo(sSource,Tags)
# Obtiene la posición de un "Tag" o etiqueta.
#
def GetIndexVideo(sSource,Tags):
   return sSource.find(Tags)

#
# GetVideoTitle(sSource)
# Obtiene el título del vídeo.
#
def GetVideoTitle(sSource):
   sSource = sSource[2000:5500]
   Begin = GetIndexVideo(sSource,'<meta name="title" content="')+28
   sSource = sSource[Begin:]
   End = GetIndexVideo(sSource,'>')-1
   sSource = sSource[:End]
   if ' ' in sSource:
sSource = sSource.replace(' ','_')
   return sSource

#
# GetVideoURL(sSource)
# Obtiene la URL de descarga del vídeo.
#
def GetVideoURL(sSource):
   sSource = sSource[9000:30000]
   Begin = GetIndexVideo(sSource,'<begin>')+7
   sSource = sSource[Begin:]
   End = GetIndexVideo(sSource,'id=')+19
   sSource = sSource[:End]+'&title=Video(WS_Downloader)'
   return sSource


#
# GetSavePath(Title)
# Obtiene la ruta en la cual se guardará el vídeo, teniendo en cuenta
# el sistema operativo.
#
def GetSavePath(Title):
   if os.name == 'posix':
return os.getenv('HOME')+'/'+Title+'.flv'
   if os.name == 'nt':
return os.getenv('HOMEDRIVE')+'\\'+Title+'.flv'

#
# DownloadStatus(Bloque, Tamano, Total)
# Muestra el estado de la descarga.
#
def DownloadStatus(Bloque, Tamano, Total):
   Cantidad = Bloque * Tamano / 1024000.0
   Total = Total / 1024000.0
   print 'Cantidad descargada: %s MB de %s MB ...' % (round(Cantidad,1),round(Total,1))
   if Cantidad >= Total:
       print 'Descarga finalizada.'

#
# DownloadVideo(sURL, sName, sStatus)
# Descarga el vídeo de los servidores de YouTube.
#
def DownloadVideo(sURL, sName, sStatus):
   try:
       Download = urllib.urlretrieve(sURL, sName, sStatus)
       return Download[0]
   except:
       print 'Error el descargar.'
       exit()

def __main__():
   __Help__ = '''
__        ______    ____                      _                 _
\ \      / / ___|  |  _ \  _____      ___ __ | | ___   __ _  __| | ___ _ __
\ \ /\ / /\___ \  | | | |/ _ \ \ /\ / / '_ \| |/ _ \ / _` |/ _` |/ _ \ '__|
 \ V  V /  ___) | | |_| | (_) \ V  V /| | | | | (_) | (_| | (_| |  __/ |  
  \_/\_/  |____/  |____/ \___/ \_/\_/ |_| |_|_|\___/ \__,_|\__,_|\___|_|  
   © Cibernodo & DaW - Labs
   Uso:
   ./WS_Downloader.py <Opción> <Id>
   
   Opciones:
       -D     : Descargar video directamente.
       -G     : Obtener URL de descarga.
       -help  : Ver Ayuda.
              '''

   try:
       Opt = sys.argv[1]
       if Opt == '-help':
           print __Help__
           
       if len(sys.argv) > 2:
           Id = URLDecode(GetSourceCode('http://www.youtube.com/watch?v='+sys.argv[2]))
           Title = GetSavePath(GetVideoTitle(Id))
           URL = GetVideoURL(Id)

           if Opt == '-G':
               print '======== Video URL ========\n',URL

           elif Opt == '-D':
               DownloadVideo(URL,Title,DownloadStatus)
               
   except:
       print __Help__
             
if __name__ == "__main__":
  __main__()





Más Información:
DaW - Labs | WS Downloader: ¡Descarga vídeos de YouTube!
Cibernodo | WS Downloader: ¡Descarga vídeos de YouTube!

Follow me on Twitter: @windhack | Visit my website: www.daw-labs.com

"The only thing they can't take from us are our minds."

Novlucker

El code esta bien estructurado y es muy entendible :P
Seguro que esas listas Char y By contemplan todos los valores que pueden aparecer? :-\

Código (python) [Seleccionar]
from urllib import url2pathname
import re

def URLDecode(sURL):
    finder = re.compile('%\d+[A-Z]{0,1}')
    chars = list(set(finder.findall(sURL)))
    for i in chars:
        sURL = sURL.replace(i,hex2char(i))
    return sURL

def hex2char(char):
    char = url2pathname(char)
    if len(char)>1:
        char = hex2char(char)
    return char


Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

.:WindHack:.

Al principio traté de hacer una función que me limpiara todos los valores codificados, muy parecida a la que has puesto pero lastimosamente no me dio el resultado que esperaba ya que me complicó un poco más todo (¡Jejeje!).

Con el resultado poco satisfactorio tomé la decisión de hacer la función usando listas, pues me sirvió y ayudó bastante para obtener la URL del vídeo más fácilmente, aunque como bien dices, no podía contemplar todos los valores posibles pero sí los estrictamente necesarios. Además podía establecer la igualdad que yo quisiera. Por ejemplo %7C le puse como valor <begin> Lo que me indicaba que allí empezaba el enlace hacia el servidor. ¡Jejejeje!


De todos modos...¡Muchas gracias Novlucker!  ;D

Follow me on Twitter: @windhack | Visit my website: www.daw-labs.com

"The only thing they can't take from us are our minds."

Novlucker

Bueno, en la función que he dejado también se podría agregar lo relativo a una lista de excepciones como lo que comentas del begin :P
Si prefieres utilizar las listas te sugiero algo, cambiarlas por la versión correcta (a mi criterio) de lo que necesitas, un diccionario :P

Igual todo lo que sugiero puede ser más que nada de "estética", buen trabajo ;D

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

EvilGoblin

Baja HD --? se podria implementar bajar 720p o 1080p ?
Experimental Serial Lain [Linux User]

.:WindHack:.

@Novlucker: Muchas gracias por las sugerencias, las tendré en cuenta para las próximas versiones. ¡Jejeje!.  :D

@EvilGoblin: El formato de descarga predeterminado es FLV MQ (Medium Quality - 640x360), pero de igual manera, esperamos agregar en la próxima versión soporte para HD y otros formatos como 3GP y MP4. Aunque dejo como dato, es mucho mejor y más confiable recurrir a la opción -G  :rolleyes:



~ Saludos.,

Follow me on Twitter: @windhack | Visit my website: www.daw-labs.com

"The only thing they can't take from us are our minds."