Conversion base de données avec pandas

Fermé
Matthieu221 Messages postés 10 Date d'inscription vendredi 4 novembre 2022 Statut Membre Dernière intervention 8 août 2023 - Modifié le 8 nov. 2022 à 15:15
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 - 10 nov. 2022 à 11:35

Bonjour à tous,

Dans le code ci dessous j'extrais des données d'un site web (titres articles, date publi, et 2 résumés) . Je range cela dans le dictionnaire "Dico"* et j'appelle celui ci via la liste "Liste" pour que pandas puisse me le convertir sous forme de tableau .

Mon problème est que cette conversion ne fonctionne pas (le Dico est bien rempli et la liste également) et j'ignore pourquoi .

Je précise que je débute en python (ça se verra certainement dans le code :D ) donc je veux bien que vous m'expliquiez votre réponse pour que je puisse bien comprendre.

Merci pour votre aide !

Matthieu

---------------

from bs4 import BeautifulSoup
import pandas as pd
import requests

url = "https://www.crossject.com/fr/news/nos-actualites?page="

for pages in range(1, 4):
    r = requests.get(url + str(pages))
    # print(url + str(pages) + '/')
    soup = BeautifulSoup(r.content, "html.parser")

    for article in soup.select('.views-row'):
        publi=article.select_one('time').text
        if article.select_one('h3') is not None:
          titre = article.select_one('h3').text
        else:
          titre = ""
        if article.select_one('p') is not None:
           resume = article.select_one('p').text
        else:
          resume = ""
        if article.select_one('a') is not None: 
          resumee = article.select_one('a').text
        else:
          resumee = ""

    Liste = []
    Dico = {
        "Publication" : publi,
        "Titres" : titre,
        "Resume" : [resume, resumee]
    }
    Liste.append(Dico)
    BD = pd.DataFrame(Liste, columns=["Publication", "Titres", "resume", "resumee"])
    BD.head()


Windows / Chrome 106.0.0.0

A voir également:

2 réponses

mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802
Modifié le 8 nov. 2022 à 15:29

Bonjour,

Plusieurs recommandations préalable :

  • Merci de partager les extraits de code comme expliqué ici.
  • Attention à l'indentation et aux espaces (voir les corrections que j'ai apportées).
  • En python, les noms qui débutent par une majuscules sont normalement réservées aux classes, donc tes variables devraient avoir un nom qui commence par une minuscule (exemple : ma_variable)
  • Choisis des noms de variables parlants. Dans ce qui suit, je renomme Dico en entry et Liste en entries.

Au niveau du code, il y a des incohérences :

  • À ce stade, tu réinitialises entries à chaque tour de boucle, or je pense que ton boucle est plutôt d'accumuler les enregistrement à chaque itération. Donc ta variable entries devrait être déclarée avant le boucle for, enrichies dans la boucle for, et une fois complètement peuplée (à la sortie de la boucle for), converti en DataFrame.
  • Ensuite, tes variables resumee et resume sont rassemblées dans une liste, mais vu les colonnes de ta DataFrame, il faudrait les garder séparées.
  • Il faut que les clés de entry et les noms de colonnes soient cohérent, sinon pandas ne peut pas s'y retrouver (notamment, il faut choisir entre "Resumee" et "resumee")
  • Il y a à mon avis des erreurs au niveau des requêtes bs4 car certains champs ne sont pas extraits (mais comme tu ne dis pas ce que tu veux extraire, difficile de savoir comment les corriger).

 Une fois corrigé, ton code pourrait ressembler à ceci :

from bs4 import BeautifulSoup
import pandas as pd
import requests 

url = "https://www.crossject.com/fr/news/nos-actualites?page="

entries = list() 
for pages in range(1, 4):
    r = requests.get(url + str(pages))
    # print(url + str(pages) + '/')
    soup = BeautifulSoup(r.content, "html.parser")

    for article in soup.select('.views-row'):
        publi = article.select_one('time').text
        if article.select_one('h3') is not None:
          titre = article.select_one('h3').text
        else:    
          titre = ""
        if article.select_one('p') is not None:
           resume = article.select_one('p').text
        else:    
          resume = ""
        if article.select_one('a') is not None:
          resumee = article.select_one('a').text
        else:    
          resumee = ""

    entry = {
        "Publication" : publi, 
        "Titres" : titre, 
        "resume" : resume,
        "resumee" : resumee
    }
    print(entry)
    entries.append(entry)
bd = pd.DataFrame(entries, columns=["Publication", "Titres", "resume", "resumee"])
bd.head()

Résultat :

  Publication Titres resume                       resumee
0  05/05/2021                Partenariat Crossject/Cenexi
1  05/05/2021                Partenariat Crossject/Cenexi
2  05/05/2021                Partenariat Crossject/Cenexi

Bonne chance

0
Matthieu221 Messages postés 10 Date d'inscription vendredi 4 novembre 2022 Statut Membre Dernière intervention 8 août 2023
Modifié le 10 nov. 2022 à 11:32

Bonjour Mamiemando,

merci de t'être penché sur mon problème et merci pour tes réponses claires . 

Quand je vois le résultat obtenu, je constate qu'il y a toujours un problème . En effet avec mon code je n'avais que le résultat de la dernière ligne et avec le tiens j'ai ce même résultat mais répété cette fois . 

Pour que tu puisses voir ce que je cherche à mettre sous forme de tableau sous pandas, j'ai modifié ton code(ci dessous) en ajoutant print dans mes conditions au début du code et en mettant sous forme de commentaires la transformation des données avec pandas.  (Par contre désolé mais je ne sais pas comment tu fais pour présenter ton code avec les numéros des lignes ).

from bs4 import BeautifulSoup
import pandas as pd
import requests 

url = "https://www.crossject.com/fr/news/nos-actualites?page="
entries = list() 

for pages in range(1, 4):
    r = requests.get(url + str(pages))
    # print(url + str(pages) + '/')
    soup = BeautifulSoup(r.content, "html.parser")

    for article in soup.select('.views-row'):
        publi = print(article.select_one('time').text)
        if article.select_one('h3') is not None:
          titre = print(article.select_one('h3').text)
        else:    
          titre = ""
        if article.select_one('p') is not None:
           resume = print(article.select_one('p').text)
        else:    
          resume = ""
        if article.select_one('a') is not None:
          resumee = print(article.select_one('a').text)
        else:    
          resumee = ""

"""
    entry = {
         "Publication" : publi, 
         "Titres" : titre, 
         "resume" : resume,
         "resumee" : resumee
    }
    print(entry)
    entries.append(entry)

bd = pd.DataFrame(entries, columns=["Publication", "Titres", "resume", "resumee"])
bd.head()
"""

Merci beaucoup pour ton aide 

Matthieu

0
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802
10 nov. 2022 à 11:35

Bonjour,

Quand je vois le résultat obtenu, je constate qu'il y a toujours un problème . En effet avec mon code je n'avais que le résultat de la dernière ligne et avec le tiens j'ai ce même résultat mais répété cette fois 

Quel est le résultat attendu / que veux-tu extraire concrètement des pages que tu crawles ? Car le problème vient sûrement de ton code BeautifulSoup.

(Par contre désolé mais je ne sais pas comment tu fais pour présenter ton code avec les numéros des lignes ).

Voir les explications dans ce lien.

Bonne chance

0