IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

encoding : je me tire les cheveux [Python 3.X]


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut encoding : je me tire les cheveux
    Bonjour,

    J'ai un énorme problème, je suis devenu chauve ... Non, je déconne, ce n'est pas un problème d'être chauve !
    Plus sérieusement, je m'entraine en ce moment à scraper des sites et je scrappe un site avec plus de 500 000 articles avec différentes langes, dont le japonais qui m'ennuie.
    Lorsque je veux écrire dans un fichier csv, je suis obligé de faire en encoding sinon Python me mets un message d'erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    with open(f"{date}-données.csv","a",encoding="UTF-16") as fichier_extract:
                fichier_extract.write(f"{str(dico)}\n")
    Je suis allé à taton pour définir le meilleur encoding UTF-16 et UTF-8, voir d'autres mais je n'arrive jamais à un truc propre.
    Selon vous lequel utiliser pour gérer au mieux les différentes langues, les indices monétaires, etc etc ... sans contrarier Python ?

    N'ayant rien trouver comme encodage, je me suis dit "tant pis fais avec de toute façon le japonais te sert à rien" sauf que lorsque je veux convertir les données dans le fichier CSV, je ne sais quel séparateur mettre et qui me permettrait d'avoir une conversion propre par colonne ... J'ai essayé comme vous le voyez ci-dessous le signe § mais aussi le ù, le # le µ, etc etc mais à chaque fois j'ai pas mal de ligne qui merdent dans la conversion car le sigle apparait déjà dans le texte et donc n'est pas un séparateur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dico = "§".join([str(date),marque.strip(),description.strip(),prix.strip(),frais_port.strip(),pays.strip()])
    J'ai voulu mettre deux séparateurs car cela réduit la probabilité de les avoir à la suite dans un encodage pas terrible mais excel ne me le permets pas.

    J'ai ensuite essayé de nettoyer les textes avec caractères spéciaux avant l'écriture avec Python pour éviter l'encoding mais je n'y suis pas arrivé.

    Avez-vous une idée, sauriez-vous m'aider ?

    Un grand merci.

    Damien

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 651
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut
    Bonjour,

    ce n'est pas indiqué dans le code HTML des sites ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Pour bien comprendre l'encoding, il faut connaitre la base. Et la base, pour Python3, c'est l'unicode. Toute chaine écrite en Python est écrite en unicode.
    Il convient donc, quand tu lis une data externe, de connaitre son encoding (ce qui rejoint ici la remarque de N_BaH sur le fait que cette info devrait être dispo quelque part) afin de pouvoir la convertir en unicode à l'entrée. Et il faut faire cette opération le plus tôt possible.
    Ensuite, dans ton code, t'es tranquille. Tu peux manipuler la data en interne, tout sera bien géré question encoding.
    Ensuite, à la sortie, il te faut convertir la data dans l'encoding cette fois de ton choix. Je vois que tu utilises utf-16 mais généralement le plus universel est l'utf-8 (ou alors tu veux réécrire le fichier dans son encoding originel).

    Après si par malchance tu ne connais pas l'encoding de tes datas input, il existe la librairie "chardet" qui peut le sniffer (il faut alors lire la data sous sa forme binaire) et te donner un résultat sous forme probabiliste
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> import chardet
    >>> with open("/etc/passwd", "rb") as fp:
    ...     chardet.detect(fp.read())
    ... 
    {'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
    >>>
    La probabilité est donnée dans le champ "confidence".
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut Merci
    Bonjour Sve@r,

    Merci pour cette réponse que je vais étudier.
    Le problème, comme certains ici sans doute et comme tu l'as bien marqué, c'est que je fais du python sans avoir de base du tout : j'essaie d'apprendre un peu la théorie chez moi et j'apprends aussi avec la pratique donc il y a énormément de choses que je ne maitrise pas, ne comprends pas ou n'imagine même pas que cela existe ...
    J'essaie pourtant de lire de la littérature mais l'autoformation a ses limites : j'y ai passé 4h hier pour essayer plein de choses, essayer plein d'encoding différents.

    Je vais regarder si je trouve une sorte d'information quelque part sur l'encoding "afin de pouvoir convertir en unicode à l'entrée" (même cette partie de phrase, je vais devoir la coder pour la comprendre

    Pour l'utf-16 que j'ai utilisé, j'y suis allé à taton comme je l'ai expliqué : j'ai encodé en utf-8 et ce n'était "pas joli" alors j'ai pris l'utf-16 qui est moins pire.
    C'est vraiment du pifomètre car je ne maitrise pas et fais des expériences sur le tas.

    Encore merci.

    Damien




    Citation Envoyé par Sve@r Voir le message
    Bonjour
    Pour bien comprendre l'encoding, il faut connaitre la base. Et la base, pour Python3, c'est l'unicode. Toute chaine écrite en Python est écrite en unicode.
    Il convient donc, quand tu lis une data externe, de connaitre son encoding (ce qui rejoint ici la remarque de N_BaH sur le fait que cette info devrait être dispo quelque part) afin de pouvoir la convertir en unicode à l'entrée. Et il faut faire cette opération le plus tôt possible.
    Ensuite, dans ton code, t'es tranquille. Tu peux manipuler la data en interne, tout sera bien géré question encoding.
    Ensuite, à la sortie, il te faut convertir la data dans l'encoding cette fois de ton choix. Je vois que tu utilises utf-16 mais généralement le plus universel est l'utf-8 (ou alors tu veux réécrire le fichier dans son encoding originel).

    Après si par malchance tu ne connais pas l'encoding de tes datas input, il existe la librairie "chardet" qui peut le sniffer (il faut alors lire la data sous sa forme binaire) et te donner un résultat sous forme probabiliste
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> import chardet
    >>> with open("/etc/passwd", "rb") as fp:
    ...     chardet.detect(fp.read())
    ... 
    {'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
    >>>
    La probabilité est donnée dans le champ "confidence".

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut
    Super Sve@r, j'avance comme colombo dans mon enquête, enfin je voulais dire comme l'inspecteur gadget plutôt ...
    Bref, effectivement j'ai vu qu'il y avait des infos sur le code html en début du site

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>Chrono24 - vente et achat de montres de luxe à l'international</title>
    <meta name="description" content="Acheter&nbsp;&amp;&nbsp;vendre des montres neuves&nbsp;&amp;&nbsp;d'occasion sur Chrono24 et dans le monde entier. Plus de 500&nbsp;000 montres de marque de Rolex, Breitling, Omega et autres à des prix avantageux. Chrono24 a été fondé en 2003 et est le leader du marché mondial des montres de luxe en ligne.">
    <meta name="audience" content="all">
    <meta name="robots" content="index, follow, noodp">
    <meta name="language" content="fr">
    <meta name="distribution" content="global">
    <meta property="fb:admins" content="1278455374">
    <meta name="google-site-verification" content="wCf_m8eIu8KaUyYrUE4jd_g5Hhb98HUmdA0-qo9aJf0">
    A priori c'est de l'UTF-8. Je ne sais pas trop à quoi cela va me servir dans mon problème mais je vais essayer de regarder sur internet si je trouve des informations par rapport à ce que tu m'as écris, ainsi que N_Bah

    Damien

    Citation Envoyé par Sve@r Voir le message
    Bonjour
    Pour bien comprendre l'encoding, il faut connaitre la base. Et la base, pour Python3, c'est l'unicode. Toute chaine écrite en Python est écrite en unicode.
    Il convient donc, quand tu lis une data externe, de connaitre son encoding (ce qui rejoint ici la remarque de N_BaH sur le fait que cette info devrait être dispo quelque part) afin de pouvoir la convertir en unicode à l'entrée. Et il faut faire cette opération le plus tôt possible.
    Ensuite, dans ton code, t'es tranquille. Tu peux manipuler la data en interne, tout sera bien géré question encoding.
    Ensuite, à la sortie, il te faut convertir la data dans l'encoding cette fois de ton choix. Je vois que tu utilises utf-16 mais généralement le plus universel est l'utf-8 (ou alors tu veux réécrire le fichier dans son encoding originel).

    Après si par malchance tu ne connais pas l'encoding de tes datas input, il existe la librairie "chardet" qui peut le sniffer (il faut alors lire la data sous sa forme binaire) et te donner un résultat sous forme probabiliste
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> import chardet
    >>> with open("/etc/passwd", "rb") as fp:
    ...     chardet.detect(fp.read())
    ... 
    {'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
    >>>
    La probabilité est donnée dans le champ "confidence".

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut Merci
    Salut,

    Effectivement, il y a marqué que c'est du UTF-8 au début du code, je vais regarder comment faire avec cette info.
    Encore merci.

    Damien

    Citation Envoyé par N_BaH Voir le message
    Bonjour,

    ce n'est pas indiqué dans le code HTML des sites ?

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par damienvialla Voir le message
    c'est que je fais du python sans avoir de base du tout
    J'ai un peu envie de demander "est-ce la meilleure façon de faire du Python?"...

    Citation Envoyé par damienvialla Voir le message
    Je vais regarder si je trouve une sorte d'information quelque part sur l'encoding "afin de pouvoir convertir en unicode à l'entrée" (même cette partie de phrase, je vais devoir la coder pour la comprendre
    Quand tu lis l'info, tu précises "je la lis dans l'encoding dans lequel elle est encodée". Si c'est un fichier que tu lis, tu places cette indication à l'ouverture du fichier (fopen(..., "r", encoding=...)). Et dans le pire des cas, si ton outil de récupération de data ne permet pas de spécifier l'encoding alors tu lis la donnée sous sa forme brute (ie le binaire) ce qui te donne du bytes auquel tu peux appliquer la méthode "decode()" pour décoder son format ce qui te donne au final une chaine standard Python (donc unicode)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> b=b"123"
    >>> print(b, type(b))
    b'123' <class 'bytes'>
    >>> s=b.decode("utf-8")
    >>> print(s, type(s))
    123 <class 'str'>
    >>> bb=s.encode("utf-8")
    >>> print(bb, type(bb))
    b'123' <class 'bytes'>
    >>> print(b == bb)
    True

    Citation Envoyé par damienvialla Voir le message
    Pour l'utf-16 que j'ai utilisé, j'y suis allé à taton comme je l'ai expliqué : j'ai encodé en utf-8 et ce n'était "pas joli"
    Si l'info d'origine n'est pas bien écrite, tu pourras l'encoder dans ce que tu veux, ça ne changera rien. L'encoding ce n'est pas la baguette magique de Cendrillon qui change la citrouille en carrosse, c'est juste une traduction. Métaphore: si tu écris un français approximatif et que tu le traduis en anglais, tu auras un anglais approximatif.
    Le point de départ c'est "la lecture de l'info". Tant que ce que tu lis ne sera pas récupéré nickel, rien ne pourra marcher. Mais à l'inverse, une fois que tu le lis correctement c'est réglé car tu le ressors ensuite comme tu en as envie.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    721
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 721
    Par défaut
    En plus de figurer dans la section HEAD de la page scrappée, Il y a probablement un header HTTP qui indique l'encoding aussi.

    Et pour convertir d'un charset vers un autre, par exemple pour tout normaliser vers UTF-8 il y des outls comme iconv. Mais en fait les fonctions encode et decode de Python devraient déjà suffire.

    Effectivement ce sera du cas par cas. Pour des sites plus anciens dans nos contrées vous verrez souvent de l'encoding ISO8859-1 avec des variantes pour le cyrillique etc. Si vous traitez tout comme de l'Unicode certaines parties comme les accents seront mal interprétées et le texte deviendra relativement illisible.

  9. #9
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut
    J'ai un peu envie de te répondre ... Sve@r, ta question est rhétorique et toi comme moi on sait que ce n'est pas la bonne façon de faire mais je fais ce que je peux avec ce que j'ai.
    J'essaie la littérature internet, les vidéos youtube, les exos openclassroom, j'ai même acheté "le Python pour les nuls" ...
    Je me suis même dit que j'allais me payer un étudient proche de chez moi pour prendre des cours particuliers mais je dois faire attention aux finances étant au chomage.

    Je suis d'ailleurs entrain de voir avec pôle emploi quel serait la meilleur façon de faire

    En fait, j'essaie de scraper un site de montres (j'adore les montres) pour m'entrainer et certaines personnes écrivent en japonais donc quand je viens pomper le html entre balise, python bug ... Je vais regarder cette histoire de binaire et le décode.
    Après le japonais n'est pas trop un problème, c'est juste que ca me donne des caractères chelou qui fait que je ne peux pas séparer correctement mon fichier csv.
    J'ai alors regardé si avec Python on ne peut pas directement écrire dans des colonnes différentes ma liste et à priori y a un truc comme writer.writerow qui pourrait permettre, cela fait 2h que je suis dessus. Oui, je suis assez pugnace malgré mon incompétence

    J'adore ta métaphore, elle est très représentative et comme dit ma belle fille dans son talkie walkie : reçu 5/5.
    Maintenant il faut que j'arrive à bien comprendre comment bien lire ...
    On va essayer sur google : "comment bien lire un htm pour le parser et le mettre correctement en csv".

    Encore merci pour le temps que tu prends.

    Damien



    Citation Envoyé par Sve@r Voir le message
    J'ai un peu envie de demander "est-ce la meilleure façon de faire du Python?"...


    Quand tu lis l'info, tu précises "je la lis dans l'encoding dans lequel elle est encodée". Si c'est un fichier que tu lis, tu places cette indication à l'ouverture du fichier (fopen(..., "r", encoding=...)). Et dans le pire des cas, si ton outil de récupération de data ne permet pas de spécifier l'encoding alors tu lis la donnée sous sa forme brute (ie le binaire) ce qui te donne du bytes auquel tu peux appliquer la méthode "decode()" pour décoder son format ce qui te donne au final une chaine standard Python (donc unicode)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> b=b"123"
    >>> print(b, type(b))
    b'123' <class 'bytes'>
    >>> s=b.decode("utf-8")
    >>> print(s, type(s))
    123 <class 'str'>
    >>> bb=s.encode("utf-8")
    >>> print(bb, type(bb))
    b'123' <class 'bytes'>
    >>> print(b == bb)
    True


    Si l'info d'origine n'est pas bien écrite, tu pourras l'encoder dans ce que tu veux, ça ne changera rien. L'encoding ce n'est pas la baguette magique de Cendrillon qui change la citrouille en carrosse, c'est juste une traduction. Métaphore: si tu écris un français approximatif et que tu le traduis en anglais, tu auras un anglais approximatif.
    Le point de départ c'est "la lecture de l'info". Tant que ce que tu lis ne sera pas récupéré nickel, rien ne pourra marcher. Mais à l'inverse, une fois que tu le lis correctement c'est réglé car tu le ressors ensuite comme tu en as envie.

  10. #10
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut
    Salut

    Je vais regarder cela.
    J'adore comme pour les "pro", la notion d'encodage et décodage parait naturelle ... Pour nous les padawan, c'est le côté obscure de la force

    Damien

    Citation Envoyé par binarygirl Voir le message
    En plus de figurer dans la section HEAD de la page scrappée, Il y a probablement un header HTTP qui indique l'encoding aussi.

    Et pour convertir d'un charset vers un autre, par exemple pour tout normaliser vers UTF-8 il y des outls comme iconv. Mais en fait les fonctions encode et decode de Python devraient déjà suffire.

    Effectivement ce sera du cas par cas. Pour des sites plus anciens dans nos contrées vous verrez souvent de l'encoding ISO8859-1 avec des variantes pour le cyrillique etc. Si vous traitez tout comme de l'Unicode certaines parties comme les accents seront mal interprétées et le texte deviendra relativement illisible.

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par damienvialla Voir le message
    j'ai même acheté "le Python pour les nuls" ...
    Dommage d'avoir payé un truc gratuit. Checke ma signature...

    Citation Envoyé par damienvialla Voir le message
    On va essayer sur google : "comment bien lire un htm pour le parser et le mettre correctement en csv".
    1) lire l'info
    2) l'écrire en CSV
    Pour le 1 bon ça dépend de l'outil que tu utilises. Mais pour le 2, tu as le module "csv" qui est fait pour ça (enfin il est surtout fait pour la lecture car c'est ce qu'il y a de plus dur, pour l'écriture il suffit d'écrire en texte avec un séparateur mais sinon il peut aussi écrire du CSV).

    Citation Envoyé par damienvialla Voir le message
    J'adore comme pour les "pro", la notion d'encodage et décodage parait naturelle
    En fait ce qui compte vraiment c'est le moment où tu lis l'info externe. C'est là que tu dis à Python "je lis tel encoding" et Python (enfin c'est plutôt l'outil de lecture) traduit ce qui est lu en unicode. Mais en plus vu que le header que tu nous as montrés semble indiquer que le site est en utf-8, tu ne devrais même pas avoir de souci vu que l'utf-8 est le standard (quand Python lit un truc sans spécification, il considère que c'est de l'utf-8 par défaut). Presque j'ai envie de dire que le souci se situerait dans ce que tu sors au final. Le seul indice c'est ce fichier_extract.write(f"{str(dico)}\n") qui m'ennuie un peu (que contient "dico"? Pourquoi forcer en str()???)
    Là un print(dico, type(dico)) pourrait apporter un éclaircissement...

    Citation Envoyé par damienvialla Voir le message
    Encore merci pour le temps que tu prends.
    Pas de souci, on est là pour ça.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #12
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par damienvialla Voir le message
    J'adore comme pour les "pro", la notion d'encodage et décodage parait naturelle ... Pour nous les padawan, c'est le côté obscure de la force
    Au cas où vous l'ignoriez, tout est codé en une suite de 0 et de 1 (en binaire quoi) appelés bits.
    Un tas de 8 bits s'appelle octet ou byte,...
    Et donc tout est codage/décodage (même les instructions qu'exécute la machine).
    Après sûr que si on se lance à coder avec Python sans avoir une idée du fonctionnement d'un ordinateur, il manque les bases, le fondement sur quoi s'appuyer pour comprendre. Mais c'est votre choix...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut
    J'ai commencé à lire ton pdf il y a quelques mois ... je l'ai même imprimé en R/V 2 par pages et tu m'avais fait comprendre que je n'étais pas l'ami des arbres
    Quel travail tu as fait ! C'est incroyable.
    Après, il y a des passages qui sont encore compliqués alors j'ai voulu faire décanter mais je vais me remettre à cette passionnante lecture.

    J'utilise bien le module csv pour écrire dans le fichier mais si je ne mets pas l'encodage (alors que le site chrono24 que je scrape précise que c'est bien uft-8 donc normalement pas de soucis comme tu dis), je vais me retrouver avec ce type d'erreur : UnicodeEncodeError: 'charmap' codec can't encode character '\u202f' in position 113: character maps to <undefined>

    Je suis encore loin de Néo dans la matrice ...

    Citation Envoyé par Sve@r Voir le message
    Dommage d'avoir payé un truc gratuit. Checke ma signature...


    1) lire l'info
    2) l'écrire en CSV
    Pour le 1 bon ça dépend de l'outil que tu utilises. Mais pour le 2, tu as le module "csv" qui est fait pour ça. Un exemple ici. Le truc il peut lire n'importe quel encoding car justement il utilise chardet pour le sniffer.


    En fait ce qui compte vraiment c'est le moment où tu lis l'info externe. C'est là que tu dis à Python "je lis tel encoding" et Python (enfin c'est plutôt l'outil de lecture) traduit ce qui est lu en unicode. Mais en plus vu que le header que tu nous as montrés semble indiquer que le site est en utf-8, tu ne devrais même pas avoir de souci vu que l'utf-8 est le standard (quand Python lit un truc sans spécification, il considère que c'est de l'utf-8 par défaut). Presque j'ai envie de dire que le souci se situerait dans ce que tu sors au final. Le seul indice c'est ce fichier_extract.write(f"{str(dico)}\n") qui m'ennuie un peu (que contient "dico"? Pourquoi forcer en str()???)
    Là un print(dico, type(dico)) pourrait apporter un éclaircissement...


    Pas de souci, on est là pour ça.

  14. #14
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par damienvialla Voir le message
    je vais me retrouver avec ce type d'erreur : UnicodeEncodeError: 'charmap' codec can't encode character '\u202f' in position 113: character maps to <undefined>
    Le message dit que vous voulez encoder le caractère unicode '\u202f' avec un encodage par défaut (probablement cp1252 sous Windows), si on précise utf-8:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> '\u202f'.encode('utf-8')
    b'\xe2\x80\xaf'
    avec cp1252:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> '\u202f'.encode('cp1252')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\py_env\py_3.11\Lib\encodings\cp1252.py", line 12, in encode
        return codecs.charmap_encode(input,errors,encoding_table)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    UnicodeEncodeError: 'charmap' codec can't encode character '\u202f' in position 0: character maps to <undefined>
    >>>
    C'est bien d'avoir choisi un tuto mais ce n'est pas un livre de cuisine avec des recettes toutes faites mais un guide pour apprendre à programmer avec Python en y passant du temps pour comprendre comment ça marche (décortiquer les messages d'erreurs en fait partie).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #15
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut
    01000010 01101111 01101110 01101010 01101111 01110101 01110010 00100000 01110111 01101001 01111010 01110100 01110010 01101001 01100011 01101011 01110011 00101100 00100000 00001010 01001010 01100101 00100000 01110011 01110101 01101001 01110011 00100000 01101001 01101110 01100011 01101111 01101101 01110000 11000011 10101001 01110100 01100101 01101110 01110100 00100000 01100001 01110101 00100000 01110000 01101111 01110011 01110011 01101001 01100010 01101100 01100101 00100000 01100101 01101110 00100000 01110000 01110010 01101111 01100111 01110010 01100001 01101101 01101101 01100001 01110100 01101001 01101111 01101110 00100000 01101101 01100001 01101001 01110011 00100000 01101010 01100101 00100000 01110011 01100001 01110110 01100001 01101001 01110011 00100000 01110001 01110101 01100101 00100000 01110100 01101111 01110101 01110100 00100000 01100101 01110011 01110100 00100000 01111010 11000011 10101001 01110010 01101111 00100000 01100101 01110100 00100000 01110101 01101110 00101100 00100000 01100011 01101111 01101101 01101101 01100101 00100000 01101101 01100101 01110011 00100000 01101110 01101111 01110100 01100101 01110011 00100000 01100101 01101110 00100000 01100100 01101001 01100011 01110100 11000011 10101001 01100101 00100000 01100100 01100101 00100000 01101100 00100111 11000011 10101001 01110000 01101111 01110001 01110101 01100101 00100000 00111010 01101111 00101001 00001010 00001010 01000100 01100001 01101101 01101001 01100101 01101110

    Citation Envoyé par wiztricks Voir le message
    Au cas où vous l'ignoriez, tout est codé en une suite de 0 et de 1 (en binaire quoi) appelés bits.
    Un tas de 8 bits s'appelle octet ou byte,...
    Et donc tout est codage/décodage (même les instructions qu'exécute la machine).
    Après sûr que si on se lance à coder avec Python sans avoir une idée du fonctionnement d'un ordinateur, il manque les bases, le fondement sur quoi s'appuyer pour comprendre. Mais c'est votre choix...

    - W

  16. #16
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par damienvialla Voir le message
    01000010 01101111 01101110 01101010 01101111 01110101 01110010 00100000 01110111 01101001 01111010 01110100 01110010 01101001 01100011 01101011 01110011 00101100 00100000 00001010 01001010 01100101 00100000 01110011 01110101 01101001 01110011 00100000 01101001 01101110 01100011 01101111 01101101 01110000 11000011 10101001 01110100 01100101 01101110 01110100 00100000 01100001 01110101 00100000 01110000 01101111 01110011 01110011 01101001 01100010 01101100 01100101 00100000 01100101 01101110 00100000 01110000 01110010 01101111 01100111 01110010 01100001 01101101 01101101 01100001 01110100 01101001 01101111 01101110 00100000 01101101 01100001 01101001 01110011 00100000 01101010 01100101 00100000 01110011 01100001 01110110 01100001 01101001 01110011 00100000 01110001 01110101 01100101 00100000 01110100 01101111 01110101 01110100 00100000 01100101 01110011 01110100 00100000 01111010 11000011 10101001 01110010 01101111 00100000 01100101 01110100 00100000 01110101 01101110 00101100 00100000 01100011 01101111 01101101 01101101 01100101 00100000 01101101 01100101 01110011 00100000 01101110 01101111 01110100 01100101 01110011 00100000 01100101 01101110 00100000 01100100 01101001 01100011 01110100 11000011 10101001 01100101 00100000 01100100 01100101 00100000 01101100 00100111 11000011 10101001 01110000 01101111 01110001 01110101 01100101 00100000 00111010 01101111 00101001 00001010 00001010 01000100 01100001 01101101 01101001 01100101 01101110
    7361766f69723f20632765737420756e6520646f6e6ec3a9652071756920747261696e652064616e7320766f7472652074c3aa7465206d61697320717569206e6520736520747261647569742070617320656e207361766f69722c2073696e6f6e20766f7573206e6520706f73657269657a207061732064652074656c6c6573207175657374696f6e7320737572206c27656e636f64696e672e
    note: en hexa, c'est plus compact et c'est toujours des 0 et des 1.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  17. #17
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut
    Bien joué Wiztricks :o)
    Je ne sais rien mais j'en suis conscient. J'essaie de mieux faire mais je fais ce que je peux :o)

    En attendant, je ne suis pas fier de moi mais en encodant en utf-8-sig, cela a résolu mon problème.
    Je ne suis pas fier car j'ai trouvé cela au hasard et j'ai mis une rustine sur la jambe de bois de mon problème mais chacun se bat avec ses armes :o)

    Damien

    Citation Envoyé par wiztricks Voir le message
    7361766f69723f20632765737420756e6520646f6e6ec3a9652071756920747261696e652064616e7320766f7472652074c3aa7465206d61697320717569206e6520736520747261647569742070617320656e207361766f69722c2073696e6f6e20766f7573206e6520706f73657269657a207061732064652074656c6c6573207175657374696f6e7320737572206c27656e636f64696e672e
    note: en hexa, c'est plus compact et c'est toujours des 0 et des 1.

    - W

  18. #18
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par damienvialla Voir le message
    je vais me retrouver avec ce type d'erreur : UnicodeEncodeError: 'charmap' codec can't encode character '\u202f' in position 113: character maps to <undefined>
    Tu ne voudrais pas mettre ton code entier qu'on regarde mieux ce que tu fais et comment tu le fais? Sauf si tu as peur qu'on te pique tes montres... Et en attendant je te recommande cette page. Ce site (aujourd'hui hélas mort) m'a plus appris en Python que tous les tutos que j'avais pu trouver.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  19. #19
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par damienvialla Voir le message
    En attendant, je ne suis pas fier de moi mais en encodant en utf-8-sig, cela a résolu mon problème.
    C'est un encoding windows qui marque les 2 premiers octets (le sig est pour signature) pour que les applications Windows sachent que faire du fichier (texte). Mais python n'a pas ce genre de problème sauf si on lit ce genre de fichier (mais on était parti à écrire des CSV à partir du contenu de pages HTML récupérées je ne sais où...)
    => Votre premier soucis est de bien décrire le(s) problème(s) rencontrés car s'ils se ressemblent, ils n'ont pas tous la même cause ni les mêmes solutions.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  20. #20
    Membre averti
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Avril 2023
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2023
    Messages : 33
    Par défaut
    Ce que femme veut, heu pardon, ce que Sve@r veut, Dieu veut ... :o)
    Tu trouveras ci-dessous mon code et désolé si je te fais saigner les yeux ...

    Je suis conscient que je m'attaque à des trucs difficile pour un ultra débutant mais j'apprends au fur et à mesure par contre je vais mettre les bouchée doubles pour progresser même si j'ai certaines limites de compréhension sans interlocuteur en face

    Je suis ouvert à tout commentaire, proposition et autre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    import requests
    from bs4 import BeautifulSoup
    import pandas as pd
    import datetime
    import time
    import os
     
    #permet de savoir combien de temps dure l'execution
    date = datetime.date.today()
    start = time.time()
     
    #efface le fichier portant le même nom pour en faire un nouveau
    if os.path.exists(f"{date}-donnéeschrono24.csv"):
        os.remove(f"{date}-donnéeschrono24.csv")
     
    #met les titres de colonne dans le fichier csv qui est variable avec fstring sur la date
    #encodage en utf-8-sig qui marche bien, pourquoi ?
    dico1 = "§".join(["Date", "Marque","Descritpion","Prix","frais de port","Pays"])
    with open(f"{date}-donnéeschrono24.csv","a",encoding="utf-8-sig") as fichier_extract:
            fichier_extract.write(f"{str(dico1)}\n")
     
    #je boucle sur l'ensemble des pages. Attention, comment savoir en automatique combien il y a de pages ???
    #aujourd'hui obligé d'aller voir le nombre de pages qu'il y a sur le site internet
    for i in range(1,5):
        url = f"https://www.chrono24.fr/search/index.htm?accessoryTypes=&dosearch=true&query=montre&searchexplain=true&showpage={i}&sortorder=11&watchTypes=U"
        html = requests.get(url, headers={'User-Agent': 'Mozilla Firefox'})
        soup = BeautifulSoup(html.content, 'html.parser')
        #différentes annonces car toutes les infos ne se trouvent pas dans la même "div class"
        annonces_texte = soup.find_all("div", {"class":"d-flex justify-content-between align-items-end m-b-1"})
        annonces_marque = soup.find_all("div", {"class":"p-x-2 p-x-sm-0"})
        annonces_vrai_marque = soup.find_all("div", {"class":"article-item-container wt-search-result carousel-test"})
        dico = {}
     
        j=""
        k=""
     
        for i,j,k in zip(annonces_texte, annonces_marque,annonces_vrai_marque):
            try:
                prix = i.find("div", {"class":"text-bold"}).get_text()
            except:
                prix = "no price"
     
            try:
                frais_port = i.find("div", {"class":"text-muted text-sm"}).get_text()
            except:
                frais_port = "Pas de frais de port"
            #marque generique ne marche pas, je n'arrive pas à la chopper dans data-manufacturer, exemple "Patek Philippe" 
            marque_generique = k.find("a", {"data-manufacturer="})
            marque = j.find("div", {"class":"text-bold text-ellipsis"}).get_text()
            description = j.find("div", {"class":"text-ellipsis m-b-2"}).get_text()
            pays = i.find("span", {"class":"text-sm text-uppercase"}).get_text()
     
            #mets toutes les variables dans la liste. Obligé de mettre date et marque_generique en string ...
            dico = "§".join([str(date),str(marque_generique),marque.strip(),description.strip(),prix.strip(),frais_port.strip(),pays.strip()])
     
            #toujours encoding utf-8-sig, pourquoi ?
            # \n pour passage à la ligne
            with open(f"{date}-donnéeschrono24.csv","a", encoding="utf-8-sig") as fichier_extract:
                fichier_extract.write(f"{str(dico)}\n")
     
    # indique fin du temps pour durée d'execution
    end = time.time()
    elapsed = end - start
    print(f'Temps d\'exécution : {int(elapsed)} s')
    Citation Envoyé par Sve@r Voir le message
    Tu ne voudrais pas mettre ton code entier qu'on regarde mieux ce que tu fais et comment tu le fais? Sauf si tu as peur qu'on te pique tes montres... Et en attendant je te recommande cette page. Ce site (aujourd'hui hélas mort) m'a plus appris en Python que tous les tutos que j'avais pu trouver.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. HTML encode UTF-8 et les accents
    Par Spir dans le forum Langage
    Réponses: 7
    Dernier message: 28/12/2008, 21h03
  2. Réponses: 3
    Dernier message: 06/09/2008, 01h18
  3. Couper les cheveux en 4
    Par kaukau dans le forum Haskell
    Réponses: 9
    Dernier message: 27/02/2008, 12h34
  4. X forwarding tiré par les cheveux
    Par Eusebius dans le forum Réseau
    Réponses: 32
    Dernier message: 16/06/2006, 10h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo