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 :

Récupération du prix + envoi mail


Sujet :

Réseau/Web Python

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Travailleur social
    Inscrit en
    Janvier 2023
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Travailleur social

    Informations forums :
    Inscription : Janvier 2023
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Récupération du prix + envoi mail
    Bonjour à tout le monde
    Je suis en train d'apprendre à coder en Python et après avoir travaillé sur quelques projets "clé en main" je me lance dans la création d'un code pour continuer mon apprentissage. J'ai donc de petites bases, je comprends en partie les liens entre les fonctions principales ainsi que la logique et la structure d'un code Python.

    Mon projet ici est de créer un script qui me permet de relever une fois par jour le prix d'un article sur un site et de m'envoyer un mail si le prix a évolué. Dans ce cas-ci, rien d'original, c'est pour les langes de ma fille ... Je me doute que ce projet ne vend pas du rêve mais je trouvais que c'était un bon moyen pour continuer à découvrir cette technique.

    Je me fais aider par l'IA de ChatGPT car je trouve vraiment intéressant la façon de proposer un code en réponse à une demande mais également sa façon de pouvoir m'expliquer le processus du script. Je ne suis donc pas l'auteur de A à Z du code et ouvert à toute modification me permettant d'arriver à mon objectif. Je parcours également Github pour savoir ce qui est déjà édité dans d'autres projets.

    Pour faire étape par étape, j'ai testé divers parties du code :

    Test d'envoi de mail via SMTPLIB et MIMETEXT
    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
     
    import smtplib
    from email.mime.text import MIMEText
     
    # Paramètres du compte Outlook
    outlook_user = "your_email@outlook.com"
    outlook_password = "your_password"
     
    # Destinataire de l'e-mail
    to_email = "recipient_email@example.com"
     
    # Contenu de l'e-mail
    email_text = "Ceci est un e-mail de test envoyé à travers un compte Outlook avec SMTPLIB."
    msg = MIMEText(email_text)
    msg['Subject'] = "E-mail de test"
    msg['From'] = outlook_user
    msg['To'] = to_email
     
    # Connexion au serveur SMTP d'Outlook
    server = smtplib.SMTP('smtp-mail.outlook.com', 587)
    server.starttls()
    server.login(outlook_user, outlook_password)
     
    # Envoi de l'e-mail
    server.sendmail(outlook_user, to_email, msg.as_string())
     
    # Déconnexion du serveur
    server.quit()
     
    print("E-mail envoyé avec succès!")
    => OK, mail bien reçu. J'avais essayé avant avec Yagmail mais j'ai changé de projet car il semble qu'il n'est plus possible de baisser la sécurité de la boite chez Gmail.

    Test de récupération du contenu de la page

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    import requests
     
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
    }
     
    url = 'https://www.colruyt.be/fr/produits/28742'
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        print("Page récupérée avec succès")
    else:
        print("Erreur lors de la récupération de la page")
    => Avec le code suivant, je reçois une réponse positive. Toutefois je n'ai pas vu ce qu'il a concrètement récupéré.

    Test de relevé de prix avec BeautifulSoup

    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
    from bs4 import BeautifulSoup
     
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
    }
     
    # URL de l'article à surveiller
    url = 'https://www.colruyt.be/fr/produits/28742'
     
    # Récupération de la page web de l'article
    page = requests.get(url, headers=headers)
    soup = BeautifulSoup(page.content, 'html.parser')
     
    # Récupération du prix de l'article
    price = soup.find('span', class_='price-info__unit-price').get_text()
     
    # Affichage du prix
    print(price)
    => Ici, il me donne le message d'erreur suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     File "/home/pi/PriceMonitor003", line 16, in <module>
        price = soup.find('span', class_='price-info__unit-price').get_text()
    AttributeError: 'NoneType' object has no attribute 'get_text'
    Donc voici où je bloque. Auriez-vous des ressources à me proposer? J'ai déjà fait différentes recherches mais je pense ne pas être encore assez à l'aise avec Python pour trouver comment solutionner mon problème.

    Dans un premier temps, j'essaie d'extraire un prix pour faire fonctionner mon script mais mon objectif final est d'extraire une partie précise du prix car le site inscrit le prix normal et ensuite le prix à l'achat de X pièces et c'est ce dernier qui m'intéresse.

    Nom : Capt001.png
Affichages : 237
Taille : 10,8 Ko

    Mon objectif ici n'est pas de surcharger le serveur d'un site web c'est pour cela que je me limite à une requête par jour.

    Actuellement, mes codes sont principalement implémentés sur des Raspberry Pi Zero que je pilote via PUTTY et une connexion SSH . J'utilise Python 3.9 et je rédige le code sur Visual Studio Code.

    Actuellement, mon code complet ressemble à ceci mais est encore loin d'être fonctionnel.

    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
    import smtplib
    from email.mime.text import MIMEText
    from bs4 import BeautifulSoup
    import requests
    import time
     
    # Adresse de l'article à surveiller
    url = "https://www.colruyt.be/fr/produits/28742"
     
    # Headers pour la requête HTTP
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0;Win64) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36"
    }
     
    # Enregistrer le prix actuel de l'article
    page = requests.get(url, headers=headers)
    soup = BeautifulSoup(page.content, "html.parser")
    price = soup.find("div", class_="price").get_text()
     
    # Connexion au serveur SMTP d'Outlook
    smtp_server = "smtp-mail.outlook.com"
    smtp_port = 587
    smtp_username = "your_email@outlook.com"
    smtp_password = "your_password"
     
    # Destinataire de l'email
    to_email = "your_email@outlook.com"
     
    # Boucle de surveillance
    while True:
        # Récupération du prix actuel de l'article
        page = requests.get(url, headers=headers)
        soup = BeautifulSoup(page.content, "html.parser")
        new_price = soup.find("div", class_="price-info__price-label").get_text()
     
        # Vérifie si le prix a changé
        if new_price != price:
            # Envoi d'un email
            message = MIMEText("Le prix de l'article a changé de " + price + " à " + new_price)
            message["From"] = smtp_username
            message["To"] = to_email
            message["Subject"] = "Changement de prix"
     
            server = smtplib.SMTP(smtp_server, smtp_port)
            server.starttls()
            server.login(smtp_username, smtp_password)
            server.send_message(message)
            server.quit()
     
            # Mise à jour du prix enregistré
            price = new_price
     
        # Attente d'une journée avant de vérifier à nouveau
        time.sleep(24*60*60)
    J'espère avoir été complet et pas trop brouillon dans mes explications... Si je peux ajouter quelque chose, n'hésitez pas à me le dire!
    Merci d'avance !
    Bonne journée

  2. #2
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 874
    Points : 3 721
    Points
    3 721
    Par défaut
    Salut,
    Citation Envoyé par Antoineconc Voir le message

    => Ici, il me donne le message d'erreur suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     File "/home/pi/PriceMonitor003", line 16, in <module>
        price = soup.find('span', class_='price-info__unit-price').get_text()
    AttributeError: 'NoneType' object has no attribute 'get_text'
    C'est parce qu'il n'y a pas de balise avec la class price-info__unit-price dans la page...

    Tu vois cette balise dans la page "dynamique" mais ce n'est pas cette page que tu récupères avec ton code...

    Ton code récupère la page "statique" qui est ensuite mise à jour via du JavaScript...

    Il y a plusieurs solutions comme l'usage de Selenium ...

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Travailleur social
    Inscrit en
    Janvier 2023
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Travailleur social

    Informations forums :
    Inscription : Janvier 2023
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Beginner. Voir le message
    Salut,C'est parce qu'il n'y a pas de balise avec la class price-info__unit-price dans la page...

    Tu vois cette balise dans la page "dynamique" mais ce n'est pas cette page que tu récupères avec ton code...

    Ton code récupère la page "statique" qui est ensuite mise à jour via du JavaScript...

    Il y a plusieurs solutions comme l'usage de Selenium ...
    Merci beaucoup pour votre réponse et vos explications. J'ai regardé les solutions comme Selenium mais j'ai vraiment du mal à cerner le fonctionnement.

    En fouillant un peu, j'ai trouvé un projet Github https://github.com/BramB-1952444/colruytPriceChecker que je n'avais pas vu avant de quelqu'un ayant fait une démarche similaire en questionnant l'API du site. J'ai essayé le code en le modifiant avec mes infos mais j'ai l'impression que le lien de l'API n'est plus d'actualité.

    J'ai donc été voir et un nouveau lien d'API existerait.
    Nom : API001.png
Affichages : 207
Taille : 35,3 Ko

    Avec le code suivant, j'ai essayé de questionner l'API mais je reçois un message d'erreur.

    Question
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import requests
     
    # URL de l'API à interroger
    url = "https://apip.colruyt.be/gateway/ictmgmt.emarkecom.cgproductretrsvc.v2/v2/v2/fr/products/780165?clientCode=CLP&placeId=681"
     
    # Envoi de la requête à l'API
    response = requests.get(url)
     
    # Vérification de la réception de la réponse
    if response.status_code == 200:
        print("Réponse obtenue avec succès.")
        print(response.json())
    else:
        print("Erreur lors de la réception de la réponse.")
    Réponse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur lors de la réception de la réponse
    Désolé si mes questions sont basiques mais je suis vraiment dans mes débuts. J'ai l'impression qu'en partant sur la solution de l'API, je suis beaucoup plus proche d'autres projets existants, c'est juste que lors de mes recherches je n'avais pas réussi à trouver une API du site.

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

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    Tu as été voir ce que donne l'url ?
    Pas d'aide par mp.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Travailleur social
    Inscrit en
    Janvier 2023
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Travailleur social

    Informations forums :
    Inscription : Janvier 2023
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par marco056 Voir le message
    Tu as été voir ce que donne l'url ?
    En effet, j'obtiens une erreur.

    Par contre, je viens d'essayer avec le lien de l'API qui était référencé dans le Github et j'obtiens une réponse positive. Cela n'avait pas fonctionné car le numéro du produit et du lieu que j'avais trouvés n'étaient pas bon.

    Merci je ne savais pas que je pouvais tester les liens d'une API dans le navigateur.

  6. #6
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 874
    Points : 3 721
    Points
    3 721
    Par défaut
    Citation Envoyé par Antoineconc Voir le message
    En fouillant un peu, j'ai trouvé un projet Github https://github.com/BramB-1952444/colruytPriceChecker que je n'avais pas vu avant de quelqu'un ayant fait une démarche similaire en questionnant l'API du site. J'ai essayé le code en le modifiant avec mes infos mais j'ai l'impression que le lien de l'API n'est plus d'actualité.
    Cet exemple est différent, là tu as une API qui permet de récupérer les informations au format JSON...

    Pour l'autre site, tu as utilisé un lien pour charger une page HTML, tu n'as pas utilisé une API...

    Citation Envoyé par Antoineconc Voir le message
    Merci beaucoup pour votre réponse et vos explications. J'ai regardé les solutions comme Selenium mais j'ai vraiment du mal à cerner le fonctionnement.
    J'ai essayé avec Selenium mais il y a quelques difficultés, il faut tout d'abord accepter les cookies en cliquant sur le bon bouton...

    Mais ensuite il ne faut pas aller trop vite...

    Cela a fonctionné au début mais au bout d'un moment on reçoit ce genre de message :

    Désolé d’avoir interrompu votre session.

    Pendant que vous étiez en train de surfer, quelque chose nous a fait penser que vous étiez peut-être un bot.
    Il y a plusieurs raisons qui peuvent expliquer cela :

    • Vous utilisez un plug-in qui bloque JavaScript dans votre navigateur.
    • Vous utilisez un VPN ou un logiciel de confidentialité souvent utilisé par des personnes malveillantes.
    • Vous êtes un super-utilisateur qui se déplace à une vitesse surhumaine sur ce site web.

    Il semblerait donc (à confirmer) qu'ils ne veulent pas qu'on utilise un robot pour naviguer sur leur site...

    Je n'insiste donc pas pour respecter leur souhait.

  7. #7
    Membre habitué
    Homme Profil pro
    Animateur Numérique
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Animateur Numérique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 195
    Points
    195
    Par défaut
    Salut,

    Citation Envoyé par Beginner. Voir le message
    Il semblerait donc (à confirmer) qu'ils ne veulent pas qu'on utilise un robot pour naviguer sur leur site...
    Oui je confirme, éjecter après quelques requêtes, l'api est plus souple, je n'ai pas pris la valeur proposée de 681 pour placeId car le prix est ne correspond à celui du site:

    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 requests
     
    PRODUCT_ID = "780165"
    PLACE_ID ="755"
     
    API = f"https://ecgproductmw.colruyt.be/ecgproductmw/v2/fr/products/{PRODUCT_ID}?clientCode=clp&placeId={PLACE_ID}"
     
    response = requests.get(API)
    data = response.json()
     
    print(data["brand"])
    print(data["name"])
    print(data["description"]+"\n")
     
    for key, val in data["price"].items():
        print(key, ":", val)

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Travailleur social
    Inscrit en
    Janvier 2023
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Belgique

    Informations professionnelles :
    Activité : Travailleur social

    Informations forums :
    Inscription : Janvier 2023
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Beginner. Voir le message
    J'ai essayé avec Selenium mais il y a quelques difficultés, il faut tout d'abord accepter les cookies en cliquant sur le bon bouton...

    Mais ensuite il ne faut pas aller trop vite...

    Cela a fonctionné au début mais au bout d'un moment on reçoit ce genre de message :



    Il semblerait donc (à confirmer) qu'ils ne veulent pas qu'on utilise un robot pour naviguer sur leur site...

    Je n'insiste donc pas pour respecter leur souhait.
    Bonjour,
    Merci beaucoup d'avoir consacré du temps à tester la solution de Selenium!

    En effet, c'est en partie pour cela que je cherche une solution qui respecte le fonctionnement du site web et qui ne génère pas plus de trafic que si je venais moi même relever manuellement de temps en temps.

    Quand un script Python relève un prix (1 à 2 fois par jour) via l'API du site est-ce que ça génère un problème particulier ?

    Actuellement, je suis bien parti sur le code avec l'API et j'avance (à mon rythme) bien. Le script fonctionne bien pour la version prise sur GitHub, le script m'envoie des mails avec le bon prix. Maintenant je rame surtout car j'essaie d'ajouter une fonction qui enregistre le prix dans un fichier CSV pour ensuite comparer avec le précédent relevé afin de déterminer si oui ou non il faut envoyer un mail notifiant un changement de prix.

    Et j'ai découvert ma première éjection du service mail...

Discussions similaires

  1. Réponses: 1
    Dernier message: 16/11/2015, 13h41
  2. Envoi mail Outlook Selon données + récupération données
    Par lindoushka dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 18/07/2014, 11h35
  3. envoi mail en python
    Par julienr2512 dans le forum Général Python
    Réponses: 1
    Dernier message: 02/05/2013, 12h16
  4. Récupération URL + envoi mail
    Par paulhen dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 07/07/2011, 09h43
  5. pb envoi mail CDONTS
    Par flatron dans le forum ASP
    Réponses: 2
    Dernier message: 30/12/2003, 16h23

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