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

Réseau/Web Python Discussion :

Problème de parsing html et d'encoding [Python 3.X]


Sujet :

Réseau/Web Python

  1. #1
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut Problème de parsing html et d'encoding
    Bonjour, je tente de parser une page web pour mon application, mais mes tests ne sont pas très concluant...
    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
    import urllib
    import urllib.request
    from http.cookiejar import CookieJar
    import chardet
     
     
    url = 'https://www.dofus.com/fr/mmorpg/encyclopedie/equipements/14080-amulette-seculaire'
     
    req = urllib.request.Request(url, None, {'User-Agent': 'Mozilla/5.0 (X11; Linux i686; G518Rco3Yp0uLV40Lcc9hAzC1BOROTJADjicLjOmlr4=) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3','Accept-Encoding': 'gzip, deflate, sdch','Accept-Language': 'en-US,en;q=0.8','Connection': 'keep-alive'})
    cj = CookieJar()
     
    opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
    response = opener.open(req)
    html = response.read()
    response.close()
     
    print(chardet.detect(html))
    et j'obtient {'encoding': None, 'confidence': 0.0, 'language': None} ..
    J'ai tenter de décoder en utf-8 mais .. UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte.

    Pourtant dans le code source de la page <meta http-equiv="content-type" content="text/html; charset=UTF-8">...

    Alors est-ce que j'ai mal compris un truc et je suis à coté de la plaque ou bien ?

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 752
    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 752
    Par défaut
    Salut,

    Citation Envoyé par flapili Voir le message
    Alors est-ce que j'ai mal compris un truc et je suis à coté de la plaque ou bien ?
    Peut être que le contenu a été zippé.
    Ce qui doit être indiqué dans les headers.

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

  3. #3
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Ceci ne te conviendrait pas ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import requests, bs4
     
    url = 'https://www.dofus.com/fr/mmorpg/encyclopedie/equipements/14080-amulette-seculaire'
     
    sess = requests.session()
    r = sess.post(url)
    print(r.text)
    #
    #soup = bs4.BeautifulSoup(r.text, 'html.parser')
    #print(soup)

  4. #4
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    Bonjour,
    Citation Envoyé par wiztricks Voir le message
    Salut,
    Peut être que le contenu a été zippé.
    Ce qui doit être indiqué dans les headers.
    - W
    J'ai cherché dans le header mais je n'est rien trouvé à se sujet, faut dire que pour le moment en html je sais pas trop quoi chercher

    marco056 ton code marche impec, j'ai l'impression que request est mieux que celui du module urllib.
    Bon maintenant il ne me reste plus qu'a faire mon parsing ... sa va être joyeux ça encore >.<

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 752
    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 752
    Par défaut
    Citation Envoyé par flapili Voir le message
    J'ai cherché dans le header mais je n'est rien trouvé à se sujet, faut dire que pour le moment en html je sais pas trop quoi chercher
    C'est ce que vous avez demandé au serveur en écrivant 'Accept-Encoding': 'gzip, deflate, sdch' dans le header du message que vous lui avez expédié... Donc il devrait vous retourner un message HTTP contenant du HTML compressé encodé en UTF-8 ou en Latin-1.

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

  6. #6
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    En effet, j'avais sortie un vieil user-agent du placard sans trop vérifier.

    Merci

  7. #7
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Citation Envoyé par flapili Voir le message
    Bonjour,

    J'ai cherché dans le header mais je n'est rien trouvé à se sujet, faut dire que pour le moment en html je sais pas trop quoi chercher

    marco056 ton code marche impec, j'ai l'impression que request est mieux que celui du module urllib.
    Bon maintenant il ne me reste plus qu'a faire mon parsing ... sa va être joyeux ça encore >.<


    Grâce à BufferBob (un grand merci à lui encore s'il passe par ici), j'ai énormément progressé depuis une semaine. Si je peux t'aider à mon tour...
    Un exemple :
    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
    import requests, bs4
     
    url = 'https://www.dofus.com/fr/mmorpg/encyclopedie/equipements/14080-amulette-seculaire'
     
    sess = requests.session()
    r = sess.post(url)
    #print(r.text)
    #
    soup = bs4.BeautifulSoup(r.text, 'html.parser')
    #print(soup)
     
    liste_content = soup.find_all("div", class_ = "ak-content")
    #for elem in liste_content:
    #    print(elem.text)
     
    for elem in liste_content:
        tag = elem.find_all("span", class_ = "ak-linker")
        for el in tag:
            print(el.text)
    Le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Galet acajou
    Poudre glaciale
    Poil d'aisselle de Missiz Frizz
    Pédoncule de Mérulor
    Oeil de Cycloïde
    Queue de Sinistrofu
    Bandelette du Comte Harebourg
    Œil de verre
    Coiffe Séculaire
    Amulette Séculaire
    Ceinture Séculaire

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 752
    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 752
    Par défaut
    Citation Envoyé par flapili Voir le message
    En effet, j'avais sortie un vieil user-agent du placard sans trop vérifier.
    Si vous voulez du HTML codé en utf-8, il faut non seulement le demander mais aussi vérifier que vous avez bien reçu le message dans le format attendu.
    Donc en bricolant le code que vous avez posté, çà donnerait:

    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
    import urllib
    import urllib.request
    from http.cookiejar import CookieJar
    import chardet
     
     
    url = 'https://www.dofus.com/fr/mmorpg/encyclopedie/equipements/14080-amulette-seculaire'
     
    req = urllib.request.Request(url, None,
           {'User-Agent': 'Mozilla/5.0 (X11; Linux i686; G518Rco3Yp0uLV40Lcc9hAzC1BOROTJADjicLjOmlr4=) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',
    #        'Accept-Encoding': 'gzip, deflate, sdch',
            'Accept': 'text/html',
            'Accept-Charset': 'utf-8',
            )
    cj = CookieJar()
     
    opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
    response = opener.open(req)
    print('Content-Encoding:', response.headers.get('Content-Encoding'))
    print('Content-Type:', response.headers['Content-Type'])
    html = response.read()
    html.decode('utf-8')
    Et vous pouvez jouer à supprimer le commentaire pour voir ce qui change.

    Ce sont les headers qu'on envoie et qu'on reçoit qui font la richesse et la versatilité du protocole HTTP.
    Le HTML, des documents échangés avec ce protocole, est beaucoup plus simple (même s'il sera bien plus pénible de décortiquer la page pour y récupérer les informations souhaitées).

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

  9. #9
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    Bonjour,
    voici un petit retour, si ça peut aider quelqu'un plus tard, mon code quasi final:

    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
    65
    66
    67
    68
    69
    70
     
    # -*- coding: utf-8 -*-
     
    import requests
    import bs4
    import json
     
    try:
    	with open('recipe.json', 'r', encoding='utf-8') as file:
    		recipe = json.load(file)
    except:
    	recipe = {}
     
     
    def get_recipe(url):
    	sess = requests.session()
    	r = sess.post(url)
    	soup = bs4.BeautifulSoup(r.text, 'html.parser')
     
    	if not soup.find_all("div", class_="ak-container ak-panel ak-crafts"): # pas de recette
    		return
     
     
    	category_of_parsed_item = soup.find("div", class_="ak-encyclo-detail-type col-xs-6") # catégorie de l'item parsé
    	if not category_of_parsed_item.text.split()[-1] in recipe:
    		recipe[category_of_parsed_item.text.split()[-1]] = {}
    	# print(category_of_parsed_item.text.split()[-1])
     
     
    	name_of_parsed_item = soup.find("h1", class_="ak-return-link") # nom de l'item parsé
    	for i in name_of_parsed_item.text.split('\n'):
    		if i:
    			name_of_parsed_item = i
    	# print(name_of_parsed_item)
     
     
    	for elem in soup.find_all("div", class_="ak-container ak-panel ak-crafts"):
    		name_of_ressource = elem.find_all("span", class_="ak-linker")
    		quantity_of_ressource = elem.find_all("div", class_="ak-front")
    		category_of_ressource = elem.find_all("div", class_="ak-text")
     
     
    	list_name_of_ressource = []
    	for i in name_of_ressource:
    		for j in i.text.split('\n'):
    			if j:
    				list_name_of_ressource.append(j)
     
    	list_quantity_of_ressource = []
    	for i in quantity_of_ressource:
    			list_quantity_of_ressource.append(int(i.text.split()[0]))
     
    	list_category_of_ressource = []
    	for i in category_of_ressource:
    		list_category_of_ressource.append(i.text)
     
    	a = []
    	for i in zip(list_quantity_of_ressource, list_name_of_ressource, list_category_of_ressource):
    		a.append(i)
     
    	recipe[category_of_parsed_item.text.split()[-1]][name_of_parsed_item] = a
     
    	with open('recipe.json', 'w', encoding='utf-8') as f:
    		json.dump(recipe, f, sort_keys=True, indent="\t", ensure_ascii=False)
     
     
    get_recipe('https://www.dofus.com/fr/mmorpg/encyclopedie/equipements/14080-amulette-seculaire')
    get_recipe('https://www.dofus.com/fr/mmorpg/encyclopedie/equipements/14097-amulette-nocturlabe')
    get_recipe('https://www.dofus.com/fr/mmorpg/encyclopedie/equipements/15184-cape-barbetoal')
    #parseur url à faire
    Il ne me reste plus qu'a faire un parseur qui récupère les urls mais c'est la même chose donc ça va..

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Parsing HTML et problème de filtre via XPath
    Par mastasushi dans le forum XML/XSL et SOAP
    Réponses: 4
    Dernier message: 11/05/2011, 09h55
  2. [Mail] Problème mail en html
    Par Vinzius dans le forum Langage
    Réponses: 6
    Dernier message: 10/09/2005, 22h51
  3. problème de validation HTML
    Par silversky dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 05/09/2005, 13h47
  4. [SAX] Problème de parsing ?
    Par Regis.C dans le forum Format d'échange (XML, JSON...)
    Réponses: 8
    Dernier message: 22/06/2005, 21h48
  5. [html][xsl]Problème valeur attribut html
    Par beho dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 16/04/2005, 13h37

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