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 :

Webscraping,boucle avec BeautifulSoup


Sujet :

Python

  1. #1
    Nouveau Candidat au Club  
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2016
    Messages : 9
    Points : 1
    Points
    1
    Par défaut Webscraping,boucle avec BeautifulSoup
    Bonjour à tous,

    je m'entraine sur Python avec BeautifulSoup et j'aimerai que mon robot puisse parcourir cet URL : https://www.nyrr.org/charities-clubs.../club-listing/

    et cliquer sur les clubs par exemple le premier club = https://www.nyrr.org/charities-clubs...listing/3runpl

    puis à l'intérieur de ces pages, j'aimerai récupérer toutes les balises 'p' qui sont dans balise 'div class = contactbox'

    J'ai cru comprendre qu'il fallait utiliser une Regex pour pouvoir parcourir un domaine en boucle mais malgré la documentation et les vidéos, je bloque sur sa création avec le re.compile :s

    Pourriez vous me donner une piste pour avancer s'il vous plait ? Merci d'avance.

    Voici mon petit bout de code qui arrive à récupérer cette information pour une page unique.

    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
    from bs4 import BeautifulSoup
    from urllib.request import Request, urlopen
    from urllib.error import HTTPError
    from urllib.error import URLError
    from datetime import datetime
    import re
    import random
    import csv
     
     
    t1 = datetime.now()
     
    req = Request('https://www.nyrr.org/charities-clubs-and-community/local-clubs/club-listing/3runpl', headers = {'User-Agent': 'Mozilla/5.0'})
     
    html = urlopen(req)
     
    bs = BeautifulSoup(html.read(), 'html.parser')
     
    for string in bs.find('div', {'class':'contactbox'}).findAll('p'):
        print(string.get_text())
     
    t2 = datetime.now()
     
    total = t2 -t1
    print('le récolte a duré exactement', total, 'plutôt rapide non ?')
    Il y a des packages inutilisés, je les prévois pour des exercices plus tard après avoir lu de la doc à leurs sujets.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Votre code devrait déjà réaliser
    récupérer toutes les balises 'p' qui sont dans balise 'div class = contactbox'
    .

    Après quand vous dites:
    J'ai cru comprendre qu'il fallait utiliser une Regex pour pouvoir parcourir un domaine en boucle mais malgré la documentation et les vidéos, je bloque sur sa création avec le re.compile :s
    sans montrer ce que vous avez essayé de faire pas facile d'imaginer à quoi vous voulez appliquez cette regex ni les difficultés que vous rencontrez.
    Difficile de vous donner des pistes pour avancer si vous ne décrivez pas un peu mieux tout çà.

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

  3. #3
    Nouveau Candidat au Club  
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2016
    Messages : 9
    Points : 1
    Points
    1
    Par défaut Regex de noob
    Salut,

    Voila la Regex que j'ai essayé de programmer mais j'ai beaucoup d'erreurs de syntaxe. En gros j'ai essayé d'adapter un exercice ou on parcours wikipedia pour récupérer tous les liens des articles relié à une même page.

    Ce que j'aimerai vraiment réussir à faire avec Python , ça serai de parcourir un bout d'url précis du style http://www.nyrr.org/charities-clubs-...listing/?????? ou l'expression régulière permettrai de faire une boucle pour trouver tous les urls à partir de cette racine.

    Quelqu'un aurait une idée de comment faire ça s'il vous plait ? Est ce que une Regex est ce qu'il y a de plus adapté ou ya t'il un moyen plus simple de le faire ?

    Merci pour votre temps.



    #from bs4 import BeautifulSoup
    #from urllib.request import Request, urlopen
    #from urllib.error import HTTPError
    #from urllib.error import URLError
    #import datetime
    #import re
    #import random
    #import csv

    #random.seed(datetime.datetime.now())

    #def Getcontactbox(balP):
    # req = Request('https://www.nyrr.org{}'.format(balP), headers = {'User-Agent': 'Mozilla/5.0'})
    # html = urlopen(req)
    # bs = BeautifulSoup(html.read(), 'html.parser')
    # return bs.find('p', {'class':'ContactBox'}).findAll('p',
    # req=re.compile('^(/charities-clubs-and-community/local-clubs/club-listing/3runpl)([A-Za-z0-9].[A-Za-z0-9])*$')
    #
    #urlloop = Getcontactbox('/charities-clubs-and-community/local-clubs/club-listing/3runpl')
    #while len(urlloop) > 0:
    # Newcontact = urlloop[random.randint(0, len(urlloop)-1)].attrs['req']
    # print(urlloop)
    # urlloop = Getcontactbox(Newcontact)

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    La recherche dans des pages html avec des expressions régulières est considérée comme peu fiable.

    Soit tu utilises pleinement Beautifulsoup soit un module inclus dans Python HtmlParser.

    Avec ton exemple ça reste simple:
    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
     
    from html.parser import HTMLParser
     
    class Parser(HTMLParser):
        def __init__(self):
            super().__init__()
            self.in_contact = False
            self.in_value = False
            self.info = False
            self.facebook = False
     
        def handle_starttag(self, tag, attrs):
            if tag == "div":
                for att in attrs:
                    if att[0] == 'class' and att[1] == "contactbox":
                        self.in_contact = True
     
            elif self.in_contact and tag == "p":
                self.in_value = True
     
            elif self.in_value and tag == "a":
                for att in attrs:
                    if att[0] == 'href':
                        self.facebook = att[1]
                self.in_contact = False
                self.in_value = False
     
        def handle_endtag(self, tag):
            if self.in_contact and tag == "div":
                self.in_contact = False
                self.in_value = False
     
        def handle_data(self, data):
            if self.in_value:
                txt = data.strip()
                if txt and txt.replace(" ", "").isdecimal():
                    self.info = txt
     
    with open("3RunPl", "r") as inf:
        content = inf.read()
     
    parser = Parser()
    parser.feed(content)
    print("Contact info: %s" % parser.info)
    print("Facebook: %s" % parser.facebook)

  5. #5
    Nouveau Candidat au Club  
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2016
    Messages : 9
    Points : 1
    Points
    1
    Par défaut Merci !
    Merci beaucoup VinsS pour ta réponse !!

    Je vais l'étudier de près et essayer de l'appliquer sur d'autres cas. MERCI ENCORE ça m'aide vraiment beaucoup

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par dariusvba Voir le message
    Ce que j'aimerai vraiment réussir à faire avec Python , ça serai de parcourir un bout d'url précis du style http://www.nyrr.org/charities-clubs-...listing/?????? ou l'expression régulière permettrai de faire une boucle pour trouver tous les urls à partir de cette racine.
    Il y a déjà pas mal de chose prête à l'emploi dans la bibliothèque standard urllib.parse.

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

  7. #7
    Nouveau Candidat au Club  
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2016
    Messages : 9
    Points : 1
    Points
    1
    Par défaut Merci Wiztricks !
    Citation Envoyé par wiztricks Voir le message
    Salut,



    Il y a déjà pas mal de chose prête à l'emploi dans la bibliothèque standard urllib.parse.

    - W


    Je vais aller voir si j'arrive à comprendre cette documentation, merci beaucoup Wiztricks !

  8. #8
    Nouveau Candidat au Club  
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2016
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Salut,

    La recherche dans des pages html avec des expressions régulières est considérée comme peu fiable.

    Soit tu utilises pleinement Beautifulsoup soit un module inclus dans Python HtmlParser.

    Avec ton exemple ça reste simple:
    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
     
    from html.parser import HTMLParser
     
    class Parser(HTMLParser):
        def __init__(self):
            super().__init__()
            self.in_contact = False
            self.in_value = False
            self.info = False
            self.facebook = False
     
        def handle_starttag(self, tag, attrs):
            if tag == "div":
                for att in attrs:
                    if att[0] == 'class' and att[1] == "contactbox":
                        self.in_contact = True
     
            elif self.in_contact and tag == "p":
                self.in_value = True
     
            elif self.in_value and tag == "a":
                for att in attrs:
                    if att[0] == 'href':
                        self.facebook = att[1]
                self.in_contact = False
                self.in_value = False
     
        def handle_endtag(self, tag):
            if self.in_contact and tag == "div":
                self.in_contact = False
                self.in_value = False
     
        def handle_data(self, data):
            if self.in_value:
                txt = data.strip()
                if txt and txt.replace(" ", "").isdecimal():
                    self.info = txt
     
    with open("3RunPl", "r") as inf:
        content = inf.read()
     
    parser = Parser()
    parser.feed(content)
    print("Contact info: %s" % parser.info)
    print("Facebook: %s" % parser.facebook)

    Grâce à ton code j'ai bien compris la logique des lists init avec self merci, mais ou est ce que je dois définir l'URL pour pouvoir scraper mon site s'il te plait ?

  9. #9
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Ben, moi dans mon exemple j'avais copié le code source de la page dans un fichier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    with open("3RunPl", "r") as inf:
        content = inf.read()
     
    parser = Parser()
    parser.feed(content)
    tu dois donc remplacer les deux premières lignes par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    req = Request('https://www...........)
    content = urlopen(req).read()

  10. #10
    Nouveau Candidat au Club  
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2016
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Ben, moi dans mon exemple j'avais copié le code source de la page dans un fichier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    with open("3RunPl", "r") as inf:
        content = inf.read()
     
    parser = Parser()
    parser.feed(content)
    tu dois donc remplacer les deux premières lignes par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    req = Request('https://www...........)
    content = urlopen(req).read()
    Ah énorme merci. Du coup le fichier 3runPl tu la save en py avec req ou le résultat en txt pour pouvoir l'utiliser comme ça ? J'imagine qu'il faut laisser le fichier dans le même dossier que son code lecture ?

  11. #11
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Non, ce n'est pas ça, moi je l'ai fais parce que j'ai affiché le source de la page avec Firefox mais toi tu peux continuer à faire comme dans ton premier code et lire le contenu de la page avec Request et read() et tu passes le contenu au parser. Pas besoin de passer par un fichier.

  12. #12
    Nouveau Candidat au Club  
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2016
    Messages : 9
    Points : 1
    Points
    1
    Par défaut Merci !
    Ok merci ! Pour l'url plutot que request j'utilise urlopen du coup mais j'ai l'impression que le site repère le crawler car je tombe sur une 403 error.
    Je n'arrive pas non plus à identifier la boucle dans l'url de ton code. Quel est le mécanisme pour changer les pages ?

    Avant j'arrivai à utiliser le headers pour simuler le browser mais la ça me dit non maintenant alors que je l'utilise de la même manière



    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
    headers = {'User-Agent': 'Mozilla/5.0'}
    #from html.parser import HTMLParser
    #from urllib.request import urlopen
    #
    #req = ("https://www.nyrr.org/charities-clubs-and-community/local-clubs/club-listing/3runpl", headers = {'User-Agent': 'Mozilla/5.0'})
    #
    #content = urlopen(req).read()
    #
    #class Parser(HTMLParser):
    #    def __init__(self):
    #        super().__init__()
    #        self.in_contact = False
    #        self.in_value = False
    #        self.info = False
    #        self.facebook = False
    # 
    #    def handle_starttag(self, tag, attrs):
    #        if tag == "div":
    #            for att in attrs:
    #                if att[0] == 'class' and att[1] == "contactbox":
    #                    self.in_contact = True
    # 
    #        elif self.in_contact and tag == "p":
    #            self.in_value = True
    # 
    #        elif self.in_value and tag == "a":
    #            for att in attrs:
    #                if att[0] == 'href':
    #                    self.facebook = att[1]
    #            self.in_contact = False
    #            self.in_value = False
    # 
    #    def handle_endtag(self, tag):
    #        if self.in_contact and tag == "div":
    #            self.in_contact = False
    #            self.in_value = False
    # 
    #    def handle_data(self, data):
    #        if self.in_value:
    #            txt = data.strip()
    #            if txt and txt.replace(" ", "").isdecimal():
    #               self.info = txt
    # 
    #
    # 
    #parser = Parser()
    #parser.feed(content)
    #print("Contact info: %s" % parser.info)
    # print("Facebook: %s" % parser.facebook)

  13. #13
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Aucun problème comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    url = "https://www.nyrr.org/charities-clubs-and-community/local-clubs/club-listing/3runpl"
    user_agent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0)'\
                      ' Gecko/20100101 Firefox/49.0'
    req = urllib.request.Request(url, data=None,  headers={"User-Agent": user_agent})
    content = urllib.request.urlopen(req).read().decode('utf-8', 'replace')
    parser = Parser()
    parser.feed(content)
    print("Contact info: %s" % parser.info)  # --> Contact info: 718 724 4390
    print("Facebook: %s" % parser.facebook)  # --> Facebook: https://www.facebook.com/3RunPl

Discussions similaires

  1. [DEBUTANT] sortir d'une boucle avec un touche particulière
    Par thibouille dans le forum Débuter
    Réponses: 4
    Dernier message: 25/10/2005, 06h44
  2. Probleme de boucle avec des processus sous UNIX
    Par sebastieng dans le forum POSIX
    Réponses: 6
    Dernier message: 15/10/2005, 18h57
  3. Boucle avec un TIBDataSet
    Par SebCBien dans le forum Bases de données
    Réponses: 4
    Dernier message: 12/09/2004, 17h33
  4. Boucle avec variable à incrémenter
    Par snoop dans le forum Linux
    Réponses: 2
    Dernier message: 19/03/2004, 11h07
  5. boucle avec condition d'arret changeante
    Par NicoH dans le forum Langage
    Réponses: 3
    Dernier message: 10/06/2003, 11h48

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