Installer un module Python

Bonjour,

je cherchais à télécharger une vidéo Youtube en utilisant Python et je me suis aperçu que le module pytube servait à cela.

C'est apparemment très simple en suivant la page https://towardsdatascience.com/the-easiest-way-to-download-youtube-videos-using-python-2640958318ab
Mais j'ai un problème avec ce module pytube : apparemment, il ne marche plus (je n'ai pas compris si c'est lors du passage de Python 2 à Python 3 ou si c'est Youtube qui a fait des modifications, ce qui a cassé pytube) mais il existe pytube3 qui fonctionne de la même manière. Je l'installe dans la console Python en faisant :
pip install pytube3
La console me répond que j'ai installé avec succès pytube3-9.6.4. Puis, je suis la page internet précédente, j'importe mon module puis je crée une instance de la classe YouTube :
from pytube import YouTube
video = YouTube('https://www.youtube.com/watch?v=NqC_1GuY3dw')
(L'adresse pointe vers une session de Mario si je comprends bien, mais en tout cas cette vidéo existe et est publique).

Et j'ai l'erreur :
pytube.exceptions.RegexMatchError: get_ytplayer_config: could not find match for config_patterns
C'est apparemment une erreur classique car mon moteur de recherche me renvoie pas mal de réponses, notamment celle-ci sur le github de pytube : https://github.com/pytube/pytube/issues/614
Les autres réponses sont de la même teneur : il faut désinstaller pytube et le réinstaller, mais depuis une source précise :
pip uninstall -y pytube3
pip install git+https ://github.com/nficano/pytube
La première ligne ne pose pas de problème, mais la seconde (que j'ai écrite en toute lettre mais le forum interprète logiquement la chaîne comme une adresse internet) me donne un problème d'encodage :
'utf-8' codec can't decode byte 0xe9 in position 308: invalid continuation byte
Et je suis bien embêté car je ne sais pas à quel caractère correspond ce 0xe9. Et personne n'a l'air d'avoir ce problème sur l'installation de ce module spécifique. J'imagine que c'est un problème d'encodage, mais je ne sais pas du tout comment résoudre ça ?

Réponses

  • Bonjour,

    Il est probable qu'un des fichiers (lequel ?) contienne des identifiants ou chaînes de caractères codés en ISO 8859-1, sans que la déclaration de codage correspondante (“encoding declaration”) n'ait été placée dans les premières lignes du fichier.

    0xE9 est LATIN SMALL LETTER E WITH ACUTE en ISO 8859-1, bref : un 'é'. Il faut sans doute identifier le ou les fichiers concernés et ajouter une déclaration de codage adéquate. Par exemple, pour UTF-8, le fichier peut commencer ainsi :
    #! /usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    (ne pas mettre la première ligne pour les modules importés mais seulement pour ceux destinés à être lancés directement comme scripts). UTF-8 est le codage par défaut depuis Python 3. Voir ici pour les noms correspondant à ISO 8859-1 (ou ISO 8859-15, voire d'autres codages : la seule valeur 0xE9 ne permet pas d'être certain du codage utilisé).

    A priori, l'erreur devrait se produire chez tous les utilisateurs de ce module sous Python 3, comme tu le suggères. Autrement, youtube-dl fonctionne bien en ligne de commande.
  • Bonjour,

    @Alban_ : je cite un passage d'une page dont tu indiques l'adresse : "... downloading videos (and potentially audio) from YouTube videos and extracting frames as images. We can use such images for various machine learning projects".

    Je ne sais pas si la manip dont tu parles est uniquement destinée à extraire les images d'une vidéo (parce qu'autrement tu pourrais facilement la télécharger depuis sa page YouTube), mais sache que des photographes du monde entier mettent certaines de leurs photos en ligne gratuitement (c'est-à-dire libres de droits), sur au moins trois sites : Unsplash, Pexels et Pixabay. Il suffit de taper un mot-clé dans le champ en haut de la page. Tu peux même trouver des images vectorielles et des vidéos.

    Sinon, pour en revenir à la librairie pytube3, le mieux est d'aller consulter la doc ou encore la page d'accueil du projet. La procédure de téléchargement semble légèrement différente de celle dont tu parles :
    from pytube import YouTube
    YouTube('https://youtu.be/9bZkp7q19f0').streams.get_highest_resolution().download()
    yt = YouTube('http://youtube.com/watch?v=9bZkp7q19f0')
    
    Tu peux commencer par mettre à jour la librairie :
    pip install pytube3 --upgrade
    
  • La déclaration de codage n’est pas nécessaire en Python 3, c’est de l’utf-8 par défaut.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • C'est ce que j'ai écrit ici. Mais dans l'hypothèse où un fichier Python est codé dans un codage autre qu'UTF-8, omettre la déclaration a de bonnes chances d'entraîner des problèmes.
  • J'ai cherché s'il y avait un é dans l'un des fichiers .py du module sur Github, mais une recherche n'a rien donné. En fait, j'ai l'impression que l'erreur signalée n'est pas vraiment résolue à mieux lire la page issues sur Github : certains disaient de mettre à jour une fonction du module, ce que j'ai fait, mais sans amélioration. Par contre, c'est effectivement très étrange que j'ai le souci d'encodage sur l'installation du module et personne d'autre apparemment.
    J'ai essayé de mettre à jour mon module mais sans amélioration (j'avais demandé comme certains le suggèrent d'installer une version spécifique)

    Pour répondre à la question de l'intérêt de tout ça, j'ai voulu faire un script qui télécharge une vidéo Youtube à la main en Python. Le souci étant qu'il faut aller lire comment est écrit le HTML de la page Youtube (je ne connais pas le HTML, donc je tente de deviner la bonne balise plutôt que de la trouver) et je suis tombé sur ce module en faisant des recherches sur Google. Évidemment, ça m'éloigne de mon objectif puisqu'il est clair que le module fait plus de choses que ce que je pensais faire basiquement. Mais je n'ai rien de spécifique à télécharger sur YT, c'est pour m'exercer (j'ai effectivement déjà utilisé Youtube-dl qui avait bien fonctionné). Rien à voir avec du machine learning, la page vers laquelle je renvoyais était simplement celle qui me semblait expliquer simplement les usage de pytube.

    Pour la déclaration que je vois partout :
    #! /usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    Je ne la marque jamais dans les scripts que j'écris car j'avais compris que Python 3 était automatiquement en utf8 (et aussi car mes scripts, qui ne sont que des exercices, ne sont pas suffisamment intéressants pour qu'il y ait un intérêt à les distribuer et donc à préciser l'encodage), ce que confirme Nicolas. Mais on est d'accord que c'est purement déclaratif ? Et quelqu'un qui écrirait cela sans se poser de question en début de chaque script qu'il produit est plus gênant que quelqu'un qui ne l'écrirait jamais ? (d'ailleurs c'est un peu la suggestion de brian sur mon souci d'encodage)
  • Tu peux oublier Python pour ce qui touche au Web (foutaise complète). Ton seul ami est JavaScript :

    YouTube Downloads

    Source
  • youtube-dl est écrit en Python et fonctionne très bien.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • nicolas.patrois a écrit:
    youtube-dl est écrit en Python et fonctionne très bien.

    Je n'en doute pas, mais il faut quand même préciser que le code Python doit être compilé en JavaScript avant de pouvoir être exécuté par un navigateur. En l'absence de cette étape tu dois passer par un terminal, ou éventuellement un notebook Jupyter, d'où une mise en œuvre nettement plus complexe que l'utilisation d'Html5 et de JavaScript, et surtout beaucoup moins facilement partageable.
  • @Alban_

    Dans ton premier message, tu as donné ce message d'erreur :
    'utf-8' codec can't decode byte 0xe9 in position 308: invalid continuation byte
    
    Cela donne une position très précise dans un fichier, mais lequel ? Sérieusement, ça n'était pas écrit au-dessus ?

    Edit : ce type de message me rappelle des choses, maintenant. Plus qu'à un problème de déclaration de codage du fichier Python, cela est à mon avis dû à un authentique bug du code de ce pytube, qui ne fait sans doute pas le .decode() nécessaire avec codage explicite pour convertir un objet 'bytes' en chaîne de caractères, ou qui le fait avec un codage inadapté à la donnée d'entrée (voir exemple simple reproductible dans mon message suivant). Il y a peut-être un « é » dans les métadonnées de ta vidéo (titre, etc.), ce qui ferait sortir du bois le bug en question. Je mets donc entre parenthèses le paragraphe suivant.

    (J'ai regardé la branche master du dépôt que tu as indiqué toujours dans ton premier message. Il y a de nombreux caractères non ASCII, mais cela semble être de l'UTF-8... sauf si j'en ai manqué un. D'où l'importance de savoir de quel fichier Python se plaignait.)
    Mais on est d'accord que c'est purement déclaratif ? Et quelqu'un qui écrirait cela sans se poser de question en début de chaque script qu'il produit est plus gênant que quelqu'un qui ne l'écrirait jamais ?
    Que veux-tu dire par « c'est purement déclaratif » ? Que ça ne change pas le fonctionnement du programme ? Si. Le programme suivant :
    #! /usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    print(ord("é"[0]))
    
    correctement sauvé en UTF-8, affiche 233 (i.e., 0xE9). Si l'on se contente alors de changer 'utf-8' en 'latin-1' et que l'éditeur de texte n'essaie pas d'être plus malin que l'utilisateur, alors le programme affiche 195. En effet, le « é » (LATIN SMALL LETTER E WITH ACUTE) est U+00E9, qui est dans la plage U+0080­ à U+07FF. Ces codes-là sont représentables avec 11 bits et les 11 bits de poids faible de l'écriture binaire de 0xE9 sont 000 1110 1001. Ceci est découpé en deux tranches ($5 + 6 = 11$) comme indiqué ici, soit 00011 et 101001. La première tranche devient le xxxxx du premier octet noté 110xxxxx dans le lien que je viens de donner, ce qui donne 11000011 en binaire, c'est-à-dire 195 en écriture décimale.

    (Le deuxième et dernier octet du codage UTF-8 de LATIN SMALL LETTER E WITH ACUTE est 10xxxxxx avec xxxxxx = 101001, autrement dit 10101001, soit 169 en écriture décimale.)

    Donc, quand on écrit un programme ou un fichier texte quelconque, le mieux est de se renseigner sur son éditeur de texte pour savoir dans quel codage il enregistre les fichiers. UTF-8 est presque toujours préférable de nos jours.
    Wilfrid a écrit:
    Python doit être compilé en JavaScript
    Il vaut mieux être aveugle...
  • @Wilfrid

    Et donc ? Pas besoin de JavaScript pour faire tourner youtube-dl.

    @Alban_

    Voici un exemple simple de bug produisant le message d'erreur que tu as cité dans ton premier post. Le programme « modélise » un code qui reçoit la chaine de caractères "éA" codée en ISO 8859-1, donc sous la forme d'un objet 'bytes'. Il tente de la convertir en objet 'str', i.e. de la décoder, mais pour cela demande implicitement à Python de l'interpréter comme de l'UTF-8, ce qui est impossible :
    #! /usr/bin/env python3
    
    print(b'\xe9A'.decode())
    
    =>
    Traceback (most recent call last):
      File "/tmp/./essai.py", line 3, in <module>
        print(b'\xe9A'.decode())
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 0: invalid continuation byte
    
    Si la donnée d'entrée est dans un codage compatible avec UTF-8, comme c'est le cas d'ASCII, alors le bug passe inaperçu :
    #! /usr/bin/env python3
    
    print(b'AA'.decode())
    
    =>
    AA
    
    C'est exactement pour ça qu'il est très important que les programmeurs comprennent le concept de codage de caractères et précisent explicitement le codage partout où il y a du texte. Sinon, on a des bugs cachés qui apparaissent au gré des données, et toute automatisation devient impossible, ou foireuse et pure perte de temps (heuristiques pour détecter le codage...).
  • brian a écrit:
    Et donc ? Pas besoin de JavaScript pour faire tourner youtube-dl

    Je ne comprends pas le sens de cette phrase. Soit tu fais tourner youtube-dl dans un terminal et tu n'as effectivement pas besoin de JavaScript, soit tu en as besoin pour le faire tourner dans un navigateur.

    Ceci dit, Python est très utilisé dans le développement Web, mais pour le back-end (côté serveur). Pour le front-end (côté client) c'est toujours le trio Html5+JavaScript+Css qui est utilisé (ou des frameworks JavaScript tels que jQuery et VueJS, que du code Python transcrit est de toute façon incapable de remplacer).
  • brian a écrit:
    Dans ton premier message, tu as donné ce message d'erreur :

    'utf-8' codec can't decode byte 0xe9 in position 308: invalid continuation byte

    Cela donne une position très précise dans un fichier, mais lequel ? Sérieusement, ça n'était pas écrit au-dessus ?

    Je copie-colle mon message d'erreur après la commande que j'ai tapé dans la console :
    pip install git+https://github.com/nficano/pytube
    Error in pip command:
    'utf-8' codec can't decode byte 0xe9 in position 309: invalid continuation byte
    

    Je dis peut-être un truc stupide, mais ce ne serait pas pip qui a un souci ? (désolé si c'est ça, comme je n'ai bêtement pas copié collé le début de mon message d'erreur, c'était impossible à deviner avec mon premier message). D'ailleurs, j'ai upgradé pip (je suis apparemment passé de la version 20.1.1 à la version 21.1) et maintenant mon é est en position 612.

    Pour la phrase sur utf8, j'avais toujours été persuadé que le type qui programme en sachant ce qu'il fait marque quel codage il a utilisé, mais à titre informatif pour celui qui utilise. J'ai reproduit l'erreur que tu signales à la fin de ton message, mais je n'ai pas encore vu que remplacer utf-8 par latin-1 change le résultat : mon éditeur ne me laisse pas enregistrer en latin-1 directement.

    Pour Python vs Javascript, je ne suis évidemment pas capable de trancher. Simplement, je fais du Python car c'est ce que je connais (et de ce que je comprends, sans être excellent quelque part, ce langage est bon partout). Évidemment, cette approche finira par avoir le défaut "avec un marteau, tout finit par ressembler à un clou".
  • Wilfrid, où as-tu lu qu'Alban_ souhaite « faire tourner [youtube-dl] dans un navigateur » ? Pourquoi parles-tu de navigateur dans cette discussion ?
  • @Alban_

    Ta suggestion n'est pas stupide, ce pourrait effectivement être pip... ou bien le setup.py de pytube exécuté par setuptools par l'intermédiaire de pip. Cela dit, après un coup d'œil rapide sur le setup.py en question, je ne vois pas d'où vient ce 0xe9. Celui qui afffiche le message d'erreur a vraiment fait un travail de cochon.

    Je ne vais pas installer pytube pour investiguer plus (connais pas et pas que ça à faire, désolé). Ce que je peux affirmer en revanche, c'est que le script Python 3 suivant télécharge ta vidéo sans problème (il s'agit de Mega Man, pas de Mario !) :
    import youtube_dl
    
    ydl_opts = {}
    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        ydl.download(['https://www.youtube.com/watch?v=NqC_1GuY3dw'])
    
    Il utilise youtube-dl, comme tu t'en seras douté. J'ai simplement pris le code ici, retiré une ligne inutile sous Python 3 et remplacé l'adresse par celle que tu as donnée.

    Pour ce qui est de reproduire mon petit test ici, dans le second cas, il ne faut surtout pas changer le codage du fichier — seulement sa déclaration de codage. En effet, il s'agit de montrer que la déclaration de codage a un effet bien réel sur le fonctionnement d'un programme Python. L'expérience n'est donc valable que « toutes choses égales par ailleurs ». Si on fait ce que je dis, la chaîne de caractères a pour longueur 2 lorsque la déclaration de codage stipule latin-1, et le programme affiche le code Unicode de son premier caractère, dont j'ai expliqué l'origine.
  • Je comprends tout à fait pour le manque de temps et d'envie, surtout que youtube-dl fonctionne effectivement sans problème (j'ai testé ton code après avoir installé youtube-dl via pip dans Python). Quand je l'avais utilisé sur un autre ordinateur, je m'en étais probablement servi dans l'invite de commande Windows et pas dans la console Python et je n'avais pas compris que ce serait aussi simple dans Python (pas de .exe à télécharger par exemple). Et disons que j'ai plus mes habitudes avec la console Python que l'invite de commande (ce n'est sans doute pas très rationnel).

    Pour Méga-man vs Mario, j'avais juste lancé 10 secondes de vidéo pour vérifier que la vidéo que j'allais lier n'était pas supprimée, j'ai conclu trop vite :-D

    Effectivement, après avoir réfléchi 2', si je change le codage en enregistrant, c'est complètement logique que ça change le codage ! Par contre, je n'arrive pas à obtenir 195, c'est possible que mon éditeur (Pyzo) force utf-8, ce qui me va bien.

    Enfin, merci à AD pour la correction de l'horrible faute d'orthographe dans mon message précédent (il y en a deux, mais l'oubli de l'accent sur la capitale me dérange moins que le é/er). En espérant ne pas en avoir ajouté dans ce message.
  • Tout est bien qui finit bien. ;-)

    J'attache mon fichier de test obtenu en sauvant ceci en UTF-8 (pas avec Emacs : il fait le malin et sauve systématiquement en ISO 8859-1 à cause de la déclaration de codage) :
    #! /usr/bin/env python3
    # -*- coding: latin-1 -*-
    
    print(ord("é"[0]))
    
    En raison de cette déclaration de codage, Python va voir ça :
    #! /usr/bin/env python3
    # -*- coding: latin-1 -*-
    
    print(ord("é"[0]))
    
    (et c'est aussi ce qu'affiche Emacs si on ouvre le fichier, car il comprend ces déclarations de codage). Voilà pourquoi la chaîne de caractères est dans ce cas composée de 2 caractères dont le premier est Ã, c'est-à-dire U+00C3, i.e. 195 en décimal. Donc le programme affiche 195. Tu peux exécuter le fichier attaché dans un terminal pour vérifier.
  • brian a écrit:
    Wilfrid, où as-tu lu qu'Alban_ souhaite « faire tourner [youtube-dl] dans un navigateur » ?

    Nulle part. C'est moi qui lui ai conseillé d'accéder à un contenu web depuis un navigateur plutôt que depuis un terminal, bien que ça n'ait pas de rapport direct avec son propos originel. Python est un excellent langage de script, facile à apprendre, et parfait pour l'analyse de données, mais il y a des cas où on a tout intérêt à utiliser des outils plus appropriés. C'est ce que je voulais dire à Alban.
Connectez-vous ou Inscrivez-vous pour répondre.