Scraping annuaire
quentin2121 Messages postés 9020 Date d'inscription lundi 24 mai 2010 Statut Membre Dernière intervention 1 mars 2025 - 6 juin 2024 à 16:57
- Scraping annuaire
- Annuaire inversé - Guide
- Annuaire algérie portable ✓ - Forum Mobile
- Annuaire sfr - Forum SFR
- Annuaire inversé suisse ✓ - Forum Mobile
- Annuaire inversé gratuit réponse immediate ✓ - Forum Réseaux sociaux
9 réponses
2 juin 2024 à 17:18
Bon, erreur d'indentation, il fallait aligner la ligne 25 sur le "IN"de la ligne 24.
Je continue. A plus tard :)
Dans ta boucle ligne 24, la variable i passe de 0 à 50
et tu l'écrase ensuite avec une chaine de caractères
Ca marche, mais ce serait plus sympa comme ça:
for _ in range(51): page = f"https://www.notaireetbreton.bzh/annuaire-notaire?page=%7Bpage_number%7D" page_number += 1 print(page)
3 juin 2024 à 14:10
Je ferais plutôt ainsi:
for page_number in range(51): page = f"https://www.notaireetbreton.bzh/annuaire-notaire?page=%7Bpage_number%7D" print(page)
3 juin 2024 à 15:41
Si je fais comme toi, jai :
File "C:\Users\quent\PycharmProjects\pythonProject\scraping\TESTS.py", line 9, in get_urls
notaire_items = html.find_all("div", {"class": "node__content clearfix"})
AttributeError: 'NoneType' object has no attribute 'find_all'
Ça marche, j'ai les 51 pages. Dans mon essai aussi ! Merci !
Modifié le 3 juin 2024 à 16:14
import re import pages import requests from bs4 import BeautifulSoup from werkzeug import urls def get_urls(html): notaire_items = html.find_all("div", {"class": "node__content clearfix"}) print(len(notaire_items)) def get_all(pages): urls [] page_number = 0 for i in range(51): i = f"https://www.notaireetbreton.bzh/annuaire-notaire?page=%7Bpage_number%7D" page_number += 1 urls.append(i) print(urls) return urls def main(): url = "https://www.notaireetbreton.bzh/annuaire-notaire?page=0" html = get_all(url) get_urls(html) main()
J'ai créé une liste urls: "urls [ ]" en ligne 15, j'ai cette erreur :
SyntaxError: invalid syntax
Enfin le prof fait comme cela ! lol
En ligne 11, il a utilisé la class "h2", je ne sais pas s'il y a un lien de cause à effet ?
3 juin 2024 à 18:06
urls = []
3 juin 2024 à 18:22
Merci !
mais tes lignes de 18 à 21 sont toujours aussi vilaines ...
il y a le fonctionnement d'un code, mais aussi son élégance
c'est vrai qu'on peut toujours écrire un plat de nouilles qui marche :-)
4 juin 2024 à 10:31
import re import pages import requests from bs4 import BeautifulSoup def get_urls(html): notaire_items = html.find_all("div", {"class": "node__content clearfix"}) print(len(notaire_items)) def get_all(pages): urls = [] page_number = 0 for i in range(51): i = f"https://www.notaireetbreton.bzh/annuaire-notaire?page=%7Bpage_number%7D" page_number += 1 urls.append(i) return urls def parse_notary(): r = requests.get("https://www.notaireetbreton.bzh/annuaire-notaire?page") soup = BeautifulSoup(r.content, "html.parser") notary = soup.find_all ('div' , class_='data-history-node-id="15687"role="article') print(len (notary)) for notaire in notaires: try: nom = notaire.find("node__content clearfix").text.strip() except AttributeError as e: nom = "" try: adresse = notaire.find('span', class_='adresse').text.strip() except AttributeError as e: adresse = "" try: adresse_finale = re.sub(r"\s+", " ", adresse) except AttributeError as e: adresse_finale = "" try: telephone = notaire.find('span', class_='telephone').text.strip() except AttributeError as e: telephone = "" try: email = notaire.find('span', class_='email').a.text.strip() except AttributeError as e: email = "" chemin = r"C:\Users\quent\PycharmProjects\pythonProject\ANNUAIRE-NOTAIRE.txt" with open(chemin, "a") as f: f.write(f"{nom}\n") f.write(f"{adresse_finale}\n") f.write(f"{telephone}\n") f.write(f"{email}\n") def parse_all_notary(): pages = get_all_pages() for page in pages: parse_notary(page) print(f"On scrape {page}") parse_all_notary() def main(): url = "https://www.notaireetbreton.bzh/annuaire-notaire?page=0" html = get_all(url) get_urls(html) main()
Erreur ligne 63 :
File "C:\Users\quent\PycharmProjects\pythonProject\scraping\TESTS.py", line 68, in <module>
pages = get_all_pages()
NameError: name 'get_all_pages' is not defined
4 juin 2024 à 11:07
il suffit de lire
la fonction ne s'appelle pas get_all_pages()
mais get_all(pages)
Modifié le 4 juin 2024 à 11:34
Fait comme tu as dit :
File "C:\Users\quent\PycharmProjects\pythonProject\scraping\TESTS.py", line 68, in <module>
File "C:\Users\quent\PycharmProjects\pythonProject\scraping\TESTS.py", line 63, in parse_all_notary
pages = get_all(pages)
UnboundLocalError: cannot access local variable 'pages' where it is not associated with a value
Comment attribuer une valeur à une variable ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionSalut, la question à se poser est quel est l'intérêt de créer une liste d'url ?
À la limite, on pourrait créer un générateur afin d'éviter ce stockage à usage unique.
def get_urls(page_number): for page in range(page_number): yield 'https://www.notaireetbreton.bzh/annuaire-notaire?page=%25d' % page for url in get_urls(50): print(url)
Mais même là, l'intérêt est nul.
Nb: évidemment il faut remplacer %25d par %d dans l'url...
4 juin 2024 à 11:32
Tu continues à copier-coller des bouts de code sans les comprendre pour les adapter à ton script...
Modifié le 4 juin 2024 à 11:48
Salut
J'ai fait un rajout au message 10.
Et surtout, je n'ai pas marqué en RESOLU le sujet.
Dommage de laissé tomber si près du but, je n'ai pas fait de copier coller bêtement comme l'autre jour, j'ai suivi au pas par pas les fonctions !
4 juin 2024 à 12:11
Modifié le 4 juin 2024 à 12:55
import re import pages import requests from bs4 import BeautifulSoup def get_urls(html): notaire_items = html.find_all("div", {"class": "node__content clearfix"}) print(len(notaire_items)) def get_all(pages): urls = [] page_number = 0 for i in range(51): i = f"https://www.notaireetbreton.bzh/annuaire-notaire?page=%7Bpage_number%7D" page_number += 1 urls.append(i) return urls def parse_notary(): r = requests.get("https://www.notaireetbreton.bzh/annuaire-notaire?page") soup = BeautifulSoup(r.content, "html.parser") notary = soup.find_all ('div' , class_='data-history-node-id="15687"role="article') print(len (notary)) for notary in notary: try: nom = notaire.find("node__content clearfix").text.strip() except AttributeError as e: nom = "" try: adresse = notaire.find('span', class_='adresse').text.strip() except AttributeError as e: adresse = "" try: adresse_finale = re.sub(r"\s+", " ", adresse) except AttributeError as e: adresse_finale = "" try: telephone = notaire.find('span', class_='telephone').text.strip() except AttributeError as e: telephone = "" try: email = notaire.find('span', class_='email').a.text.strip() except AttributeError as e: email = "" chemin = r"C:\Users\quent\PycharmProjects\pythonProject\scraping\TESTS.txt" with open(chemin, "a") as f: f.write(f"{nom}\n") f.write(f"{adresse_finale}\n") f.write(f"{telephone}\n") f.write(f"{email}\n\n") def parse_all_notarys(page=None): pages = get_all(page) for page in pages: parse_notary() print(f"On scrape {page}") parse_all_notarys() def main(): url = "https://www.notaireetbreton.bzh/annuaire-notaire?page=0" html = get_all(url) get_urls(html) main() input()
Là ça fonctionne, sauf que le document .txt ne se trouve pas dans mon répertoire donné en ligne 54 ? Il ne se génère pas en fait ! Le prof a dit de se mettre en environnement virtuel pour ce projet.
4 juin 2024 à 16:22
Je ne sais pas si la balise commune à tous les notaires est la suivante :
"node node-15523 node--type-office node--promoted node--view-mode-teaser clearxfix")
Pour ce site : https://www.notaireetbreton.bzh/annuaire-notaire?page=0
D'où l'impression du fichier texte qui ne s'effectue pas.
4 juin 2024 à 18:41
Bonsoir,
Qu'est-ce qui ne te plaît pas dans ce que je t'ai montré comme code ?
https://forums.commentcamarche.net/forum/affich-38050742-code-python-qui-ne-s-imprime-pas#61
Je t'avais pourtant indiqué que dans les pages listant les notaires, il n'y avait ni téléphone ni courriel, puis cela se voit à 'affichage, non ?
Pourquoi n'utilise-tu pas un fichier csv qui est parfaitement adapté à ce type de données ?
Cesse le copié-collé et repars d'une base saine, parce là rien n'a changé par rapport au code que tu avais montré dans ton précédent sujet.
Un prof ? Il sort d'où ton prof ? Parce que là, à te laisser patauger comme ça dans la mélasse, il a l'air un peu sadique ton prof :-/ j'espère que tu ne débourses rien pour un service si médiocre :-S
Modifié le 5 juin 2024 à 06:10
Tu n'as (encore) les connaissances suffisantes en Python pour ce genre de projet, mais ça, on te l'a déjà dit.
Avant que tu ne te décourages, voilà comment j'ai procédé (pour la première page) :
import re import requests from bs4 import BeautifulSoup BASE_URL = "https://www.notaireetbreton.bzh" def get_soup(url): r = requests.get(url) soup = BeautifulSoup(r.content, "html.parser") return soup def get_notary_informations(notary_url): soup = get_soup(notary_url) notary_name = soup.find("span", {"class": "field--name-title"}).text.strip() notary_phone = soup.find("div", {"class": "field--name-field-phone"}).text partial_contact_url = soup.find("a", {"class": "use-ajax"})['href'] notary_mail = get_notary_mail(partial_contact_url) notary_address = soup.find("div", {"class": "address"}).text notary_address = re.sub(r"[\s\n\t]+", " ", notary_address).strip() return (notary_name, notary_phone, notary_mail, notary_address) def get_notary_mail(partial_contact_url): soup = get_soup(BASE_URL + partial_contact_url) email_notary = soup.find("input", {"data-drupal-selector": "edit-email-to"}).get("value") return email_notary def show_informations(informations): for info in informations: print(info) print("") def main(): url = f"{BASE_URL}/annuaire-notaire?page=0" soup = get_soup(url) notaries_item = soup.find_all("div", {"class": "node__content clearfix"}) for notary_item in notaries_item: partial_notary_url = notary_item.find("a", href=True) notary_url = BASE_URL + partial_notary_url["href"] informations = get_notary_informations(notary_url) show_informations(informations) main()
À toi d'analyser, de tracer ce script et pourquoi pas de le modifier pour ajouter la boucle qui te permettra d'obtenir les 51 pages.
5 juin 2024 à 10:04
Merci bien, tu es vraiment sympa de m'encourager ainsi !
Modifié le 5 juin 2024 à 12:42
import re import pages import requests from bs4 import BeautifulSoup BASE_URL = "https://www.notaireetbreton.bzh" def get_soup(url): r = requests.get(url) soup = BeautifulSoup(r.content, "html.parser") return soup def get_notary_informations(notary_url): soup = get_soup(notary_url) notary_name = soup.find("span", {"class": "field--name-title"}).text.strip() notary_phone = soup.find("div", {"class": "field--name-field-phone"}).text partial_contact_url = soup.find("a", {"class": "use-ajax"})['href'] notary_mail = get_notary_mail(partial_contact_url) notary_address = soup.find("div", {"class": "address"}).text notary_address = re.sub(r"[\s\n\t]+", " ", notary_address).strip() return (notary_name, notary_phone, notary_mail, notary_address) def get_notary_mail(partial_contact_url): soup = get_soup(BASE_URL + partial_contact_url) email_notary = soup.find("input", {"data-drupal-selector": "edit-email-to"}).get("value") return email_notary def show_informations(informations, partial_contact_url=None, notary=None): for info in informations: print(info) print(notary) for notary in notary: try: nom = notary.find("span", {"class": "field--name-title"}).text.strip() except AttributeError as e: nom = "" try: adresse = notary.find('span', class_='adresse').text.strip() except AttributeError as e: adresse = "" try: adresse_finale = re.sub(r"[\s\n\t]+", " ", notary_address).strip() except AttributeError as e: adresse_finale = "" try: telephone = notary.find("div", {"class": "field--name-field-phone"}).text except AttributeError as e: telephone = "" try: notary_mail = get_notary_mail(partial_contact_url) except AttributeError as e: email = "" chemin = r"C:\Users\quent\PycharmProjects\pythonProject\scraping\NOTAIRES_ETUDESBRETONNES.txt" with open(chemin, "a") as f: f.write(f"{nom}\n") f.write(f"{adresse_finale}\n") f.write(f"{telephone}\n") f.write(f"{email}\n\n") def main(): url = f"{BASE_URL}/annuaire-notaire?page=0" soup = get_soup(url) notaries_item = soup.find_all("div", {"class": "node__content clearfix"}) for notary_item in notaries_item: partial_notary_url = notary_item.find("a", href=True) notary_url = BASE_URL + partial_notary_url["href"] informations = get_notary_informations(notary_url) show_informations(informations) main()
File "C:\Users\quent\PycharmProjects\pythonProject\scraping\NOTAIRES_ETUDES BRETONNES.py", line 37, in show_informations
for notary in notary:
TypeError: 'NoneType' object is not iterable
Que faire lorsqu'un objet int n'est pas itérable ?
"Pour corriger cette erreur, vous pouvez utiliser une boucle while ou convertir l'objet entier en un autre type de données itérable , tel qu'une liste ou une chaîne. Vous pouvez également utiliser la fonction range() pour obtenir une plage de nombres et utiliser une boucle for pour parcourir cette plage."
J'ai compris le souci, mais je sèche pour le corriger !
Et pour la boucle for, pour toutes afficher les pages, je sais qu'il faut mettre une URL dynamique, mais je suis perdu pour le faire.
En fait cela s'affiche, malgré l'erreur, mais seulement un notaire, comment terminer ma bouche for, pour tous les notaires ?
5 juin 2024 à 12:50
Mais pourquoi vouloir re-scrapper les infos avec ta boucle :
for notary in notary:
qui ne ressemble à rien, alors que ces infos existent déjà, car récupérés par la fonction
get_notary_informations()
Code :
def show_informations(informations): chemin = r"C:\Users\quent\PycharmProjects\pythonProject\scraping\NOTAIRES_ETUDESBRETONNES.txt" with open(chemin, "a") as f: for info in informations: f.write(f"{info}\n") f.write("\n\n")
Maintenant, tu n'as plus qu'à renommer cette fonction et son appel en save_informations c'est plus explicite.
Modifié le 5 juin 2024 à 13:33
def (save_informations (informations)): chemin = r"C:\Users\quent\PycharmProjects\pythonProject\scraping\NOTAIRES_ETUDESBRETONNES.txt" with open(chemin, "a") as f: for info in informations: f.write(f"{info}\n") f.write("\n\n") File "C:\Users\quent\PycharmProjects\pythonProject\scraping\NOTAIRES_ETUDES BRETONNES.py", line 41 def (save_informations (informations)): SyntaxError: invalid syntax
J'ai mal renommé l'appel de (informations): ?
Modifié le 5 juin 2024 à 13:40
Non , la fonction :
def save_informations(informations):
Et pourquoi tu me décales :
f.write("\n\n")
??? il te suffisait de copier/coller.
5 juin 2024 à 18:05
J'abandonne, il faut que je consulte, j'suis au bord de la dépression !!!!
Modifié le 5 juin 2024 à 19:00
C'est de l'humour noir, ou tu es sérieux ? J'y suis presque, je sais cela fait 10 jours que je dis ça. :)
Ta façon de faire est bonne, différente du coach, mais ne dis t'on pas que tout les chemins mène à Rome.
Bonsoir, non mais, mets toi à sa place, il te fournit un code fonctionnel récupérant ce qu'il faut dans la première page.
Tout ce que tu as à faire est de mettre les parties concernées dans une simple boucle for, ce que tu es incapable de faire alors que c'est p... de simple.
Bref, énième redite : tu ne comprends rien à ce que tu fais... la programmation c'est aussi être logique, mais comme tu n'as pas l'expérience nécessaire, tu ne peux avoir cette logique...
Cf .
Tu n'as (encore) les connaissances suffisantes en Python pour ce genre de projet, mais ça, on te l'a déjà dit.
Il serait quand même grand temps de partir suivre un tuto apprenant les bases.
5 juin 2024 à 23:50
Non, la boucle in range, il faut l'intégrer à la fonction main(), mais pour ça, il faut gérer l'indentation et intégrer la variable dans l'URL du site.
Désolé, tu as raison, je ne comprends pas. Je me suis dit, je mets la boucle in range à la suite de main(), comme je ne sais pas faire, je n'ai pas voulu aller plus loin et saloper le code à Diablo.
Gérer l'indentation, je vois ce que c'est, intégrer la variable dans l'URL, là, je
sèche. Est-ce cela :
for i in range(51): i = f"https://www.notaireetbreton.bzh/annuaire-notaire?page=%7Bpage_number%7D" page_number += 1 urls.append(i)
Modifié le 6 juin 2024 à 10:08
salut.
range en python :
https://duckduckgo.com/?q=python+la+classe+range&t=ffab&ia=web%2A
Différentes façons de formater une chaîne en python :
https://duckduckgo.com/?q=python+diff%C3%A9rentes+fa%C3%A7ons+de+formater+une+cha%C3%AEne&t=ffab&ia=web
Tu peux aussi ouvrir un interpréteur python et te servir de help.
help(range)
help('FORMATTING')
Et même lancer une documentation de tous les modules dans ton navigateur (à taper dans ta console dos) :
python -m pydoc -b
6 juin 2024 à 10:41
Bonjour,
Merci pour ces infos.
Si j'ai bien compris la fonction Range, je peux faire ainsi pour mon projet :
a = 51 for range i in range(a): print(i)
Cela m'affichera mes 50 pages de l'annuaire(de la page 0 à la page 50) ?
6 juin 2024 à 16:57
Salut Diablo !
Ton morceau de code en Message 23, il faut le copier où ? Si je le mets à suivre ton code, il donne un code zéro sans aucun affichage de texte dans la sortie console ? Si je le supprime, cela imprime bien la page 1 de l'annuaire ? Tu peux me montrer la totalité du code, au lieu de me faire me creuser les méninges, je le fais de toute façon, j'essaie de comprendre. Merci !