Página 3 de 4

Re: Scraper Themoviedb para pelisalacarta

Publicado: 16 Nov 2015, 12:57
por super_berny
Cmos escribió: En primer lugar, me he encontrado con que cuando haces una búsqueda con tmdb y quieres sacar el thumbnail/poster con la función get_poster(), a veces se produce un error porque devuelve un objeto NoneType en vez de str. Me he fijado que es porque cuando un resultado no tiene poster, en lugar de aparecer en el json como una cadena vacía, aparece como None (u'poster_path': None), pero dentro de get_poster se hace una comparación con una cadena vacía, por lo que da el error "cannot concatenate 'str' and 'NoneType' objects" y sale del try. Yo lo he solucionado así, pero no sé si este cambio puede afectar a otra cosa:

Código: Seleccionar todo

    def get_poster(self, tipo_respuesta="str", size="original"):
        ret=[]
        if not size in ("w45", "w92", "w154", "w185", "w300", "w342", "w500", "w600", "h632", "w780", "w1280", "original"): size="original"
        if self.result["poster_path"] is None: self.result["poster_path"] = "" --->Aquí es donde comprueba si es None y si es así lo convierte a un string vacío.
        if tipo_respuesta !='list':
            if self.result["poster_path"] !="":  ---> Aquí es donde da el error que comento
                return 'http://image.tmdb.org/t/p/' + size + self.result["poster_path"]
            else: return ""
        elif self.result["id"] == "": return []
Completamente de acuerdo.
Cmos escribió:Luego, he estado probando la función load_resultado(), y entre los if que encadena, creo que falta la opción de que haga algo cuando index_resultado sea superior a 0 y page sea igual que self.page. No sé si así estaría bien pero a mí me ha dado resultado:

Código: Seleccionar todo

    def load_resultado(self,index_resultado=0,page=1):
        if self.total_results <= 1: # Si no hay mas un resultado no podemos cambiar
            return None 
        if page < 1 or page > self.total_pages: page=1
        if index_resultado < 0: index_resultado=0
        if page !=self.page:
            self.__inicializar()
            self.__search(index_resultado=index_resultado, page=page)
        else: --->A partir de aquí lo que he añadido
            self.__leer_resultado(self.results[index_resultado])
Completamente de acuerdo tb.
Cmos escribió: También me pasa una cosa que en esto estoy seguro de que soy yo el que lo está haciendo mal. Cuando saco los géneros de una película y los agrego con infoLabels, veo que en cada item se van concatenando los de las anteriores, es decir, si por ejemplo la primera peli tiene "Comedia, Acción" y la segunda "Guerra", en la primera sale bien en kodi, pero en la segunda saldría "Comedia, Acción, Guerra". Este es el código que utilizo para ello, ¿cuál puede ser el fallo?

Código: Seleccionar todo

infoLabels['genre'] = ", ".join(oTmdb.result["genres"])
Esto es dificil de decir sin ver el resto del codigo. De todos modos estoy rehaciendo lo q tiene q ver con los generos.
Cmos escribió: Y ya por último que me vas a matar :lol: . He notado que tarda bastante en hacer el scraper de las películas (unos 26-27 segundos), en el caso de mi canal que tiene unas 40 por página. Mirando el log me he dado cuenta que antes de cada búsqueda en tmdb carga una url para rellenar el diccionario de géneros, por lo que en lugar de cargar 40 páginas, carga el doble. Viendo eso se me ocurrió que se podría crear el diccionario con los generos directamente como variable en el tmdb.py y no tener que cargar la misma página una y otra vez. Imagino que lo hiciste así para cargar el diccionario según el idioma de la búsqueda, pero he pensado que se podría crear dos diccionarios, uno en español y otro en inglés pues suelen ser lo más utilizados y si se hace la búsqueda en otro idioma, entonces sí rellenar de esa manera el diccionario. He hecho la prueba y pasa de, como decía, 26-27 segundos, a unos 13-14, a mí modo de ver la diferencia merece la pena. Te pongo cómo lo he puesto para verlo más claro:

Código: Seleccionar todo

----Dentro del constructor de la clase
linea 107
    temporada={}
               
    lista_generos_ES=[{u'id': 28, u'name': 'Acci\xc3\xb3n'},....
    lista_generos_EN=[{u'id': 28, u'name': 'Action'},....

-------- En el init
    def __init__(self, **kwargs):
        self.__inicializar()
        self.busqueda["idioma"]=kwargs.get('idioma_busqueda','es')
        self.busqueda["tipo"]=kwargs.get('tipo','movie')
        
        if self.busqueda["tipo"] =='movie' or self.busqueda["tipo"] =="tv":
            # Rellenar diccionario de generos en el idioma seleccionado
            url='http://api.themoviedb.org/3/genre/%s/list?api_key=57983e31fb435df4df77afb854740ea9&language=%s' %(self.busqueda["tipo"], self.busqueda["idioma"])	
            if self.busqueda["idioma"] == "es":
                lista_generos = self.lista_generos_ES
            elif self.busqueda["idioma"] == "en":
                lista_generos = self.lista_generos_EN
            else: lista_generos = self.__get_json(url)["genres"]
            for i in lista_generos:
                self.dic_generos[str(i["id"])]=i ["name"]
Espero haberme sabido explicar y a ver qué te parecen mis sugerencias y si me puedes orientar sobre el error raro de los géneros :mrgreen:
Te explicas perfectamente y de matarte nada, todo lo contrario agradezco no solo q detectes los bugs, si no q ademas aportes soluciones.
Y hablando de soluciones esta ultima si q no me acaba de convencer. En primer lugar la busqueda es por idioma y tipo de contenido (y tu solo consideras el idioma). Pero lo mas gracioso es q o bien la Api ha cambiado o bien yo estaba pensando en no se q cuando hice esta parte. Lo tengo q mirar mejor, pero creo q no hace falta ningun diccionario. Dejame q lo mire con mas cariño ...

Por otra parte, creo q buscar los datos de las 40 peliculas del listado inicial es un poco heavy. Yo lo q aconsejo es hacer la busqueda cuando ya se ha seleccionado un contenido en concreto: Cuando has de mostrar servidores de video en Peliculas o cuando en las Series, has de visualizar temporadas (o listado completo de capitulos, segun el caso) . Asi es mucho mas fluido.

Re: Scraper Themoviedb para pelisalacarta

Publicado: 17 Nov 2015, 17:26
por Cmos
super_berny escribió:Esto es dificil de decir sin ver el resto del codigo. De todos modos estoy rehaciendo lo q tiene q ver con los generos.
El código, en lo que atañe a los géneros sería como pongo a continuación. Además he visto que en el otro canal donde lo puse igual, seriecanal, también pasa lo mismo, se van añadiendo los géneros de forma sucesiva en cada item repitiendo los de los anteriores.

Código: Seleccionar todo

    infoLabels={}
    plot={}
    try:
        from core.tmdb import Tmdb
        oTmdb= Tmdb(texto_buscado=titulo, tipo= "movie")
        infoLabels['genre'] = ", ".join(oTmdb.result["genres"])
        plot['infoLabels']=infoLabels
    except:
        pass
super_berny escribió:Y hablando de soluciones esta ultima si q no me acaba de convencer. En primer lugar la busqueda es por idioma y tipo de contenido (y tu solo consideras el idioma). Pero lo mas gracioso es q o bien la Api ha cambiado o bien yo estaba pensando en no se q cuando hice esta parte. Lo tengo q mirar mejor, pero creo q no hace falta ningun diccionario. Dejame q lo mire con mas cariño ...
Tienes toda la razón, no me di cuenta de que es necesario filtrarlo también por contenido, pero he comprobado varias series (ej. Doctor Who) y en lugar de utilizar el diccionario de géneros para series (url api), utiliza el de las películas (url api), no sé por qué :?: De todas formas, si se puede hacer sin necesidad de un diccionario como dices pues mejor, menos quebraderos de cabeza xD
super_berny escribió:Por otra parte, creo q buscar los datos de las 40 peliculas del listado inicial es un poco heavy. Yo lo q aconsejo es hacer la busqueda cuando ya se ha seleccionado un contenido en concreto: Cuando has de mostrar servidores de video en Peliculas o cuando en las Series, has de visualizar temporadas (o listado completo de capitulos, segun el caso) . Asi es mucho mas fluido.
Lo sé, lo sé, es un poco heavy, pero el tiempo no me parece excesivo y el resultado es muy bueno (así se vería mi canal inkapelis). A mí al menos me gusta más de esta forma porque puedo ver datos como la sinopsis o la valoración sin tener que ir hacia delante o hacia atrás en el canal, pero no sé si lo dejaré así o que lo utilice solamente al acceder a la película en cuestión, tengo que meditarlo xD

Por cierto, me he dado cuenta que en la función get_backdrop() pasa lo mismo que en get_poster(), hace una comparación con una cadena vacía pero a veces el parámetro "backdrop_path" es None ;)

Re: Scraper Themoviedb para pelisalacarta

Publicado: 18 Nov 2015, 17:14
por super_berny
Bueno acabo de colgar en mi github la version 1.3 del scraper:

Cambios version 1.3:
- Corregido error al devolver None el path_poster y el backdrop_path
- Corregido error que hacia que en el listado de generos se fueran acumulando de una llamada a otra
- Añadido metodo get_generos()
- Añadido parametros opcional idioma_alternativo al metodo get_sinopsis()

@Cmos, si puedes pruebala y me dices antes de enviarsela a Jesus. Por otra parte, si te miras el codigo y algo no entiendes preguntalo. Por q al final no lo he hecho como tu decias.

Re: Scraper Themoviedb para pelisalacarta

Publicado: 18 Nov 2015, 22:14
por Cmos
super_berny escribió:Bueno acabo de colgar en mi github la version 1.3 del scraper:

Cambios version 1.3:
- Corregido error al devolver None el path_poster y el backdrop_path
- Corregido error que hacia que en el listado de generos se fueran acumulando de una llamada a otra
- Añadido metodo get_generos()
- Añadido parametros opcional idioma_alternativo al metodo get_sinopsis()

@Cmos, si puedes pruebala y me dices antes de enviarsela a Jesus. Por otra parte, si te miras el codigo y algo no entiendes preguntalo. Por q al final no lo he hecho como tu decias.
Y me alegro de que no lo hayas hecho como yo comentaba, porque está muchísimo mejor, donde va a parar :D . He probado la nueva versión y funciona de cine, ahora como apuntas los géneros los lista sin problemas y la solución que has creado para rellenar el diccionario de géneros es perfecta, por lo que veo solo se necesita cargar una vez la página del dict si no se cambia en la consulta el idioma o el tipo de contenido, no? Así contemplas todas las opciones con el mínimo procesamiento y tarda menos tiempo.

Gracias por todo el trabajo, seguiré haciendo uso de él cada vez que pueda porque me parece de lo más completo ;)

Re: Scraper Themoviedb para pelisalacarta

Publicado: 22 Nov 2015, 13:21
por Cmos
@super_berny, revisando el canal seriecanal que lo tenía mal planteado (creaba tonto de mí un objeto Tmdb cada vez que quería sacar la info de un episodio, lo que aumentaba exponencialmente el tiempo de carga :oops: ), me ha vuelto a aparecer el error con el None de las imágenes. Esta vez es en la función get_episodio, al final del todo cuando se concatena la url con el path de las imágenes, tanto de la temporada como del capítulo, salta el error al ser la variable None como pasaba en get_poster y get_backdrop. Por lo demás, de lujo ;)

Re: Scraper Themoviedb para pelisalacarta

Publicado: 22 Nov 2015, 18:33
por super_berny
Gracias Cmos,
Para solucionarlo podriamos modificar la partye final de la funcion get_episodio:

Código: Seleccionar todo

 ret_dic={}
        ret_dic["temporada_nombre"]=self.temporada["name"]
        ret_dic["temporada_sinopsis"]=self.temporada["overview"]
        ret_dic["temporada_poster"]=('http://image.tmdb.org/t/p/original'+ self.temporada["poster_path"])  if self.temporada["poster_path"] else ""
        
        
        episodio=self.temporada["episodes"][capitulo -1]
        ret_dic["episodio_titulo"]=episodio["name"]
        ret_dic["episodio_sinopsis"]=episodio["overview"]
        ret_dic["episodio_imagen"]=('http://image.tmdb.org/t/p/original'+ episodio["still_path"])  if episodio["still_path"] else ""
        
        return ret_dic
Pruebalo y me cuentas q yo ahora no puedo porbarlo

Re: Scraper Themoviedb para pelisalacarta

Publicado: 22 Nov 2015, 18:53
por Cmos
Justo eso era lo que cambié temporalmente para probarlo en el canal, pero esa forma de escribir un condicional en python no la conocía, me la apunto :D. El código probado y funcionando sin errores, gracias compañero!

Re: Scraper Themoviedb para pelisalacarta

Publicado: 22 Nov 2015, 19:05
por super_berny
Es el equivalente a iif(condición, si cierto, si falso) de otros lenguajes

Re: Scraper Themoviedb para pelisalacarta

Publicado: 06 Abr 2016, 19:29
por super_berny
Novedades v1.4:
  • Nueva gestion y busqueda de informacion extra para peliculas y series.
    • Uso:
      from core import tmdb
      tmdb.set_infoLabels(item, seekTmdb = True)
    • Obtener datos basicos de una pelicula:
      Antes de llamar al metodo set_infoLabels el titulo a buscar debe estar en item.fulltitle
      o en item.contentTitle y el año en item.infoLabels['year'].
    • Obtener datos basicos de una serie:
      Antes de llamar al metodo set_infoLabels el titulo a buscar debe estar en item.show o en item.contentSerieName.
    • Obtener mas datos de una pelicula o serie:
      Despues de obtener los datos basicos en item.infoLabels['tmdb'] tendremos el codigo de la serie o pelicula.
      Tambien podriamos directamente fijar este codigo, si se conoce, o utilizar los codigo correspondientes de:
      IMDB (en item.infoLabels['IMDBNumber'] o item.infoLabels['code'] o item.infoLabels['imdb_id']), TVDB (solo series, en item.infoLabels['tvdb_id']),
      Freebase (solo series, en item.infoLabels['freebase_mid']),TVRage (solo series, en item.infoLabels['tvrage_id'])
    • Obtener datos de una temporada:
      Antes de llamar al metodo set_infoLabels el titulo de la serie debe estar en item.show o en item.contentSerieName,
      el codigo TMDB de la serie debe estar en item.infoLabels['tmdb'] (puede fijarse automaticamente mediante la consulta de datos basica)
      y el numero de temporada debe estar en item.infoLabels['season'].
    • Obtener datos de un episodio:
      Antes de llamar al metodo set_infoLabels el titulo de la serie debe estar en item.show o en item.contentSerieName,
      el codigo TMDB de la serie debe estar en item.infoLabels['tmdb'] (puede fijarse automaticamente mediante la consulta de datos basica),
      el numero de temporada debe estar en item.infoLabels['season'] y el numero de episodio debe estar en item.infoLabels['episode'].
    • Ejemplos:
      He modificado el canal Oranline (peliculas) y he creado uno nuevo de series TremendaSeries.
      EDITO 2/6/16: Por cambios en las webs, los canales han dejado de funcionar :cry: Os pongo los enlaces a las ultimas versiones q funcionaban para q podais seguir los ejemplos.
      • Oranline:
        • Lineas 25-28: Si __modo_grafico__ = True se busca la informacion en http://www.themoviedb.org sino no (para las conexiones lentas o los q no les gusten los canales con poster ni fanart). La variable __perfil__ permite cambiar facilmente el color de los items entre 3 (0-2) opciones.
        • Lineas 37-40: Definicion de los perfiles de color. En este caso cada perfil tiene tres colores prefijados: color1, color2 y color3.
        • Linea 56: Ejemplo de formato (item.text_color y item.text_blod) en el titulo (label) del item durante su creacion.
        • Linea 158: Fijamos infoLabels['year'] para poder buscar una pelicula por el titulo.
        • Linea 163: Obtenemos los datos de un listado de peliculas
        • Linea 284: Obtenemos mas datos de la pelicula (ya q item.infoLabels['tmdb'] contiene el id encontrado en la primera busqueda)
        • Linea 308: Ejemplo de item del tipo TAG
      • TremendaSerie: (solo comento las novedades no citadas ya en Oranline)
        • Linea 78: Se limita el numero de series a 28 por pagina en el modo grafico, aunque la web proporciona mas.
          Con esto evitamos uno de los limites de la API de tmdb.
        • Linea 102: Obtenemos los datos de un listado de series (en item.show esta el titulo de la serie)
        • Linea 122: Para evitar el limite de la API de tmdb dividimos la serie en temporadas (aunq la web muestra todos los capitulos juntos)
        • Linea 135: Mediante el metodo Item.clone vamos 'heredando' atributos del item, entre ellos la informacion extra (item.infoLabels)
        • Linea 136: Se fija para cada temporada infoLabels['season'] con el numero correspondiente
        • Linea 140: Obtenemos los datos de todas las temporadas de la serie mediante multihilos
        • Linea 141-148: El titulo y las imagenes no se modifican automaticamente, hay q forzarlo.
        • Linea 188: Fijamos infoLabels['episode']
        • Linea 203: Obtenemos los datos de todos los capitulos de la temporada mediante multihilos

Re: Scraper Themoviedb para pelisalacarta

Publicado: 14 Abr 2016, 08:34
por super_berny
:shock:
Nadie lo ha mirado? Aunque sea por curiosidad?