1
votes

AttributeError: l'objet 'NoneType' n'a pas d'attribut 'find_all' Beautifulsoup

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])


0 commentaires

3 Réponses :


2
votes

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)


0 commentaires

3
votes

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/


0 commentaires

3
votes

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


0 commentaires