J'essaye de gratter le prix d'une maison de ce lien: https : //www.leboncoin.fr/ventes_immobilieres/offres/ile_de_france/p-2/
Et j'ai besoin de savoir ce qui ne va pas avec mon programme?
Mon programme: p >
Traceback (most recent call last): File "nv.py", line 14, in <module> for repo in repo.find_all("li", attrs={"itemscope itemtype": "http://schema.org/Offer"}): AttributeError: 'NoneType' object has no attribute 'find_all'
J'obtiens cette erreur:
import csv import requests from bs4 import BeautifulSoup with open("bc.csv", "w", newline="") as f: writer = csv.writer(f) writer.writerow(["prix", "code_postal", "description", "nombre_pieces", "surface"]) for i in range(1, 20): url = "https://www.leboncoin.fr/ventes_immobilieres/offres/ile_de_france/p-%s/" % i soup = BeautifulSoup(requests.get(url).text, "html.parser") repo = soup.find(class_="undefined") for repo in repo.find_all("li", attrs={"itemscope itemtype": "http://schema.org/Offer"}): prix = repo.find("span", {"itemprop": "priceCurrency"}) prix = prix.text if prix else "" writer.writerow([prix])
3 Réponses :
Ici, les scripts Java sont rendus sur la page. Vous pouvez utiliser à la fois du sélénium et de la belle soupe pour obtenir le résultat souhaité.
from selenium import webdriver from bs4 import BeautifulSoup driver=webdriver.Chrome('path of the chrome driver') driver.get("https://www.leboncoin.fr/ventes_immobilieres/offres/ile_de_france/p-2/") soup=BeautifulSoup(driver.page_source,'html.parser') repo = soup.find(class_="undefined") for repo in repo.find_all("li", attrs={"itemtype": "http://schema.org/Offer"}): prix = repo.find("span", {"itemprop": "priceCurrency"}) if prix.text!='': print(prix.text)
Vous essayez de rechercher quelque chose qui n'existe pas dans les données renvoyées par requêtes
.
Lorsque vous vérifierez requests.get (url) .text code>, vous verrez probablement quelque chose de similaire à:
<!-- Need permission to access data? Contact: DataAccess@datadome.co --> <html><head><title>You have been blocked</title><style>#cmsg{animation: A 1.5s;}@keyframes A{0%{opacity:0;}99%{opacity:0;}100%{opacity:1;}}</style></head><body style="margin:0"><p id="cmsg">Please enable JS and disable any ad blocker</p><script>var dd={'cid':'AHrlqAAAAAMAptz12-9nkWQAJcs_Yg==','hsh':'05B30BD9055986BD2EE8F5A199D973','t':'fe'}</script><script src="https://ct.datadome.co/c.js"></script></body></html>
ce qui entraîne l'affectation de Aucun
à la variable repo
et l'interpréteur se plaint de l'attribut non existant find_all ()
pour l'objet de type None
.
Donc, fondamentalement, vous devez vous assurer que vous avez les données correctes avant de commencer à les traiter. Vous pouvez obtenir les données sans être bloqué en utilisant Selenium et ChromeDriver , comme suggéré par KunduK dans sa réponse. Vous pouvez obtenir ChromeDriver sur http://chromedriver.chromium.org/
Le blocage et l'utilisation du sélénium ont déjà été abordés. Je vais montrer un moyen d'obtenir toutes les listes dans un joli format json où vous pouvez facilement extraire des informations. Si vous utilisez du sélénium pour accéder à chaque page, vous pouvez utiliser regex pour extraire toutes les informations de liste sur la page et passer à json.loads pour générer un objet json, exemple ici , vous pouvez facilement analyser toutes les informations par liste
from selenium import webdriver import re import json p = re.compile(r'({"req.*).*[^\r\n]') driver = webdriver.Chrome() driver.get("https://www.leboncoin.fr/ventes_immobilieres/offres/ile_de_france/p-3/") soup = bs(driver.page_source,'html.parser') data = json.loads(p.findall(driver.page_source)[0]) listings = data['data']['ads'] for listing in listings: print(listing)
Explication Regex:
Essayez-le ici