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 :

Envoi partiel d'un email, Scrapping avec Python [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Envoi partiel d'un email, Scrapping avec Python
    Bonjour à tous
    Etant nouveau, je ne sais pas si je dois poster ce qui suit ici, sinon n'hésitez pas à me dire où ^^

    Alors, le code ci-dessous permet de scrapper une page sur Ebay concernant les nouvelles annonces et plus (200 articles). J'ai mis en plus un filtre [Keywords] qui me permet de filtrer uniquement ce que je recherche soit environ 7 articles sur 200, jusqu'ici tout fonctionne.

    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    from bs4 import BeautifulSoup
    import requests
    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    import time
    import random
     
     
    #Paramètre_#############################################################################
    url ='https://www.ebay.fr/sch/267/i.html?_from=R40&_nkw=star+wars&_sop=10&_ipg=200'
    keywords = ['INTEGRALE', 'Thrawn', 'Legacy']
    email_address = 'YourGmailAccount@gmail.com'
    recipient_address = 'MyRecipent@email.com'
    subject_desc = 'Tile of the Email'
    password = 'YourPWD'
    #######################################################################################
     
    #Collecte de données sur Ebay
    def get_data(url):
        r = requests.get(url)
        soup = BeautifulSoup(r.text, 'html.parser')
        return soup
     
    def parse(soup):
        data = []
        results = soup.find_all('div', {'class' : 's-item__info clearfix'})
        for item in results:
            try:
                title = item.find('h3', {'class': 's-item__title'}).text.replace('Nouvelle annonce','')
                Price = item.find('span', {'class':'s-item__price'}).text
                Link = item.find('a', {'class' : 's-item__link'})['href']
     
                products = {'Title' : title, 'Price' : Price, 'Link' : Link}
                data.append(products)
            except:
                continue
        return data
     
    soup = get_data(url)
    book_titles = parse(soup)
     
    #Données filtrées provenant de parse(soup) en utilisant "keywords" qui sont dans les paramètres
    def filter(book_titles):
        for title in book_titles:
            for key, value in title.items():
                if key == 'Title':
                    for books in keywords:
                        if books in value:
                            for email in str(title).splitlines():
                                return(email)
     
    subj = filter(book_titles)
     
    #Envoi par email des données filtrées
    def create_message(from_address, to_address, subject, message):
        try:
            msg = MIMEMultipart()
            msg.attach(MIMEText(message))
            msg['From'] = from_address
            msg['To'] = to_address
            msg.passowrd = password
            msg['Subject'] = subject
            pass
        except:
            wait = random.uniform(0, 2*60)
            localtime = time.localtime()
            result = time.strftime("%I:%M:%S %p", localtime)
            print('ReTracking it is', result)
            time.sleep(wait)
        return msg
     
    if __name__ == '__main__':
        msg = create_message(
        from_address=email_address,
        to_address=recipient_address,
        subject=subject_desc,
        message=subj
        )
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
    server.starttls()
    server.login("YourGmailAccount@gmail.com", msg.passowrd)
    print("login success")
    server.send_message(msg)
    print("This message has been sent")
    server.quit()
    Par contre une fois le mail envoyé je reçois uniquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {'Title': 'Star Wars - Legacy Saison II T01: Terreur sur Carreras EO NEUF SOUS BLISTER', 'Price': '35,00 EUR', 'Link': 'https://www.ebay.fr/itm/304223244315?hash=item46d51e501b:g:tqIAAOSwjhZgOq-I'}
    Alors que je suis censé recevoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    {'Title': 'Star Wars - Legacy Saison II T01: Terreur sur Carreras EO NEUF SOUS BLISTER', 'Price': '35,00 EUR', 'Link': 'https://www.ebay.fr/itm/304223244315?hash=item46d51e501b:g:tqIAAOSwjhZgOq-I'}
    {'Title': 'LOT Star Wars Legacy 1 2 3 DELCOURT TBE', 'Price': '19,99 EUR', 'Link': 'https://www.ebay.fr/itm/313750655371?hash=item490cff118b:g:T0gAAOSwLXxhjsGY'}
    {'Title': 'Star Wars: Legacy of the Force: Bloodlines, Karen Traviss, Used; Good Book', 'Price': '8,30 EUR', 'Link': 'https://www.ebay.fr/itm/384496532637?hash=item5985c77c9d:g:D3cAAOSwlOxhjqgg'}
    {'Title': 'Star Wars: Legacy of the Force IX - Invincible, Denning, Troy, Used; Very Good B', 'Price': '15,42 EUR', 'Link': 'https://www.ebay.fr/itm/384496531150?hash=item5985c776ce:g:fswAAOSwBblhjqgQ'}    
    {'Title': "STAR WARS LES OMBRES DE L'EMPIRE INTEGRALE 2 EVOLUTION EN TTBE COMICS TRES RARE", 'Price': '45,00 EUR', 'Link': 'https://www.ebay.fr/itm/363619642859?hash=item54a96b6deb:g:AEoAAOSw3flhgCJR'}     
    {'Title': 'Star Wars™ Thrawn - Allianzen (Die Thrawn-Trilogie (K... | Livre | état très bon', 'Price': '12,69 EUR', 'Link': 'https://www.ebay.fr/itm/125000062368?hash=item1d1a9595a0:g:o38AAOSwsW1hjpoA'}    
    {'Title': 'BD Comics Star Wars Legacy 6 - VI. Renégat', 'Price': '30,00 EUR', 'Link': 'https://www.ebay.fr/itm/275024537109?hash=item4008bd6615:g:p44AAOSwSzJhjjNX'}
    J'avoue être coincé sur cette partie. auriez-vous une idée de ce qu'il manque ? (ou mal fait haha)
    En vous remerciant

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par oxykore Voir le message
    Etant nouveau, je ne sais pas si je dois poster ce qui suit ici, sinon n'hésitez pas à me dire où ^^
    Non non, ici c'est bien.

    Citation Envoyé par oxykore Voir le message
    Par contre une fois le mail envoyé je reçois uniquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {'Title': 'Star Wars - Legacy Saison II T01: Terreur sur Carreras EO NEUF SOUS BLISTER', 'Price': '35,00 EUR', 'Link': 'https://www.ebay.fr/itm/304223244315?hash=item46d51e501b:g:tqIAAOSwjhZgOq-I'}
    Alors que je suis censé recevoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    {'Title': 'Star Wars - Legacy Saison II T01: Terreur sur Carreras EO NEUF SOUS BLISTER', 'Price': '35,00 EUR', 'Link': 'https://www.ebay.fr/itm/304223244315?hash=item46d51e501b:g:tqIAAOSwjhZgOq-I'}
    {'Title': 'LOT Star Wars Legacy 1 2 3 DELCOURT TBE', 'Price': '19,99 EUR', 'Link': 'https://www.ebay.fr/itm/313750655371?hash=item490cff118b:g:T0gAAOSwLXxhjsGY'}
    {'Title': 'Star Wars: Legacy of the Force: Bloodlines, Karen Traviss, Used; Good Book', 'Price': '8,30 EUR', 'Link': 'https://www.ebay.fr/itm/384496532637?hash=item5985c77c9d:g:D3cAAOSwlOxhjqgg'}
    {'Title': 'Star Wars: Legacy of the Force IX - Invincible, Denning, Troy, Used; Very Good B', 'Price': '15,42 EUR', 'Link': 'https://www.ebay.fr/itm/384496531150?hash=item5985c776ce:g:fswAAOSwBblhjqgQ'}    
    {'Title': "STAR WARS LES OMBRES DE L'EMPIRE INTEGRALE 2 EVOLUTION EN TTBE COMICS TRES RARE", 'Price': '45,00 EUR', 'Link': 'https://www.ebay.fr/itm/363619642859?hash=item54a96b6deb:g:AEoAAOSw3flhgCJR'}     
    {'Title': 'Star Wars™ Thrawn - Allianzen (Die Thrawn-Trilogie (K... | Livre | état très bon', 'Price': '12,69 EUR', 'Link': 'https://www.ebay.fr/itm/125000062368?hash=item1d1a9595a0:g:o38AAOSwsW1hjpoA'}    
    {'Title': 'BD Comics Star Wars Legacy 6 - VI. Renégat', 'Price': '30,00 EUR', 'Link': 'https://www.ebay.fr/itm/275024537109?hash=item4008bd6615:g:p44AAOSwSzJhjjNX'}
    J'avoue être coincé sur cette partie. auriez-vous une idée de ce qu'il manque ? (ou mal fait haha)
    déjà ton code c'est un peu la La Foir'Fouille. Ici il y a une variable, puis une fonction, puis une autre variable... Une variable nommée "subj" (subject?) mais qui est en réalité le texte du message, une partie du code uniquement en cas d'appel direct (le test if __name__ == "__main__") une autre toujours exécutée... Bref il faudrait un peu réorganiser tout ça.

    Ensuite d'après ce que je vois, la fonctionfilter() semble ne retourner qu'une seule valeur (donc le "jusqu'ici tout fonctionne" me semble un peu prématuré surtout suite au print(subj) que j'ai effectué juste après) donc "une seule valeur retournée = une seule valeur reçue par mail". Tout est cohérent.
    Tu veux retourner plusieurs valeurs "matchant" ton filtre: te faut créer un tableau que tu remplis au fur et à mesure puis en fin de fonction tu retournes le tableau (on peut aussi créer un générateur avec yield ce qui est plus économique question mémoire mais ce sera pour plus tard).

    Accessoirement le pass est inutile et on aime bien affiner un peu plus les exceptions prévisibles plutôt que de toutes les intercepter y compris les exceptions pouvant avoir d'autres causes..
    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]

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci du retour

    déjà ton code c'est un peu la La Foir'Fouille. Ici il y a une variable, puis une fonction, puis une autre variable... Une variable nommée "subj" (subject?) mais qui est en réalité le texte du message, une partie du code uniquement en cas d'appel direct (le test if __name__ == "__main__") une autre toujours exécutée... Bref il faudrait un peu réorganiser tout ça.
    Alors j'ai nettoyé de cette manière EDIT::
    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
    #send email of data filtered
    for create_message in body:
        try:
            msg = EmailMessage()
            msg.set_content(body)
            msg['From'] = email_address
            msg['To'] = recipient_address
            msg['Subject'] = subject_desc
            pass
        except:
            wait = random.uniform(0, 2*60)
            localtime = time.localtime()
            result = time.strftime("%I:%M:%S %p", localtime)
            print('ReTracking it is', result)
            time.sleep(wait)
     
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
    server.starttls()
    server.login("YourGmailAddress@gmail.com", password)
    print("login success")
    server.send_message(msg)
    print("This message has been sent")
    server.quit()
    du coup je prend les informations écrit dans section "Paramètre" plutôt que part (if __name__ == "__main__")

    en haut j'ai remplacé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from email.message import EmailMessage
    et dernier point :
    J'ai renommé : subj = filter(book_titles) en body = filter(book_titles) pour que ce soit plus compréhensible

    Ensuite :
    Ensuite d'après ce que je vois, la fonction filter() semble ne retourner qu'une seule valeur (donc le "jusqu'ici tout fonctionne" me semble un peu prématuré surtout suite au print(subj) que j'ai effectué juste après) donc "une seule valeur retournée = une seule valeur reçue par mail". Tout est cohérent.
    le filter de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    book_titles = parse(soup)
    #Filter data collected with parse(soup) using "keywords" in the settings
    for title in book_titles:
        for key, value in title.items():
            if key == 'Title':
                for books in keywords:
                    if books in value:
                        for email in str(title).splitlines():
                            print(email)
    me donne bien tout les livres que je recherche.

    Pour finir :
    Accessoirement le pass est inutile et on aime bien affiner un peu plus les exceptions prévisibles plutôt que de toutes les intercepter y compris les exceptions pouvant avoir d'autres causes..
    Le pass me permet d'arrêter la boucle, en fait je recherche qu'un livre spécifique et je souhaite avec ce code, scrapper la page Ebay toutes les minutes (ou heures) et dès qu'un livre que je recherche est mise en ligne, la boucle s'arrête puis m'envoi l'email pour m'avertir.
    Dernière modification par Invité ; 13/11/2021 à 16h56.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par oxykore Voir le message
    du coup je prend les informations écrit dans section "Paramètre" plutôt que part (if __name__ == "__main__")
    Est-ce que tu connais le role primaire de ce test if __name__ == "__main__" et du code qu'on y affecte ?

    Citation Envoyé par oxykore Voir le message
    le filter de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    book_titles = parse(soup)
    #Filter data collected with parse(soup) using "keywords" in the settings
    for title in book_titles:
        for key, value in title.items():
            if key == 'Title':
                for books in keywords:
                    if books in value:
                        for email in str(title).splitlines():
                            print(email)
    me donne bien tout les livres que je recherche.
    Non, il "t'affiche" ce que tu recherches, ce n'est pas la même chose et la subtilité est importante !!!

    Dans cette version, la boucle contient un simple print() donc elle affiche le résultat et repart à l'itération suivante. Dans la première version, la boucle contenait un return donc là elle "renvoie" le premier résultat trouvé et quitte la fonction => pas d'itération suivante.

    Citation Envoyé par oxykore Voir le message
    Le pass me permet d'arrêter la boucle,
    Euh... je pense que tu confonds pass et break...
    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]

  5. #5
    Invité
    Invité(e)
    Par défaut
    Non, il "t'affiche" ce que tu recherches, ce n'est pas la même chose et la subtilité est importante !!!

    Dans cette version, la boucle contient un simple print() donc elle affiche le résultat et repart à l'itération suivante. Dans la première version, la boucle contenait un return donc là elle "renvoie" le premier résultat trouvé et quitte la fonction => pas d'itération suivante.
    Okay je comprends et du coup comment j'intègre ce "print()" dans le body d'un email ?

    Euh... je pense que tu confonds pass et break...
    Dans le cas sur le premier post, break ne voulais pas fonctionner, mais je sais bien qu'il me faut un "break"

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par oxykore Voir le message
    Okay je comprends et du coup comment j'intègre ce "print()" dans le body d'un email ?
    On crée la data vierge avant la boucle. Dans la boucle on la met à jour. Et en fin de boucle (donc à priori en fin de fonction) on renvoie la data.

    Exemple d'un print des valeurs
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def toto():
    	for x in ("xxx", "yyy", "zzz"):
    		print(x)
    # toto()
     
    toto()

    Exemple où là il y a renvoi des valeurs
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def toto():
    	res=list()
    	for x in ("xxx", "yyy", "zzz"):
    		res.append(x)
    	return res
    # toto()
     
    print(toto())

    Citation Envoyé par oxykore Voir le message
    Dans le cas sur le premier post, break ne voulais pas fonctionner, mais je sais bien qu'il me faut un "break"
    Il ne voulait pas fonctionner parce qu'un break, instruction destinée à interrompre une boucle, ne peut donc se mettre que dans une boucle (j'espère que tu saisis la logique du truc). Et comme ta fonction "create_message()" ne contient pas de boucle (un bloc try/except n'est pas une boucle), fatalement...
    Donc n'ayant pas de boucle dans cette fonction, tu n'as rien à breaker. Et bien évidemment l'instruction pass, elle, n'est pas là pour remplacer un break inutile.

    Si (éventuellement) cette fonction était, elle, appelée dans une boucle, et que là (encore éventuellement) tu veuilles interrompre cette boucle pour une raison X ou Y, alors c'est dans la boucle d'appel qu'il faut placer le break.
    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]

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

Discussions similaires

  1. [Python 2.X] Envois d'email comportant des accents avec python
    Par tolliob dans le forum Général Python
    Réponses: 6
    Dernier message: 13/08/2015, 08h13
  2. [Python 3.X] Email validité avec python
    Par AI_LINUX dans le forum Général Python
    Réponses: 1
    Dernier message: 31/07/2014, 16h03
  3. lecture email avec python
    Par thieduvar dans le forum Réseau/Web
    Réponses: 2
    Dernier message: 24/06/2009, 18h29
  4. Envoi d'email : SMPT_Send avec GOOGLE
    Par sieste68 dans le forum 4D
    Réponses: 6
    Dernier message: 08/01/2008, 16h11
  5. envoi d'Emails HTML avec Outlook
    Par juniorAl dans le forum C#
    Réponses: 4
    Dernier message: 20/11/2007, 17h31

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