Frage zu Beautiful Soup

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Rednaxelarekced
User
Beiträge: 17
Registriert: Mittwoch 6. März 2019, 22:04

Hallo,

schonmal vielen Dank für die Hilfe!

ich habe folgendes Problem. Ich möchte aus einer Adresse die Straße auslesen. Die Adresse besteht aber aus "Strasse, Ort, PLZ"
Jetzt habe ich die Strip() Methode genutzt und wenn ich auf einzelne Teile zugreifen will geht das ohne weiteres.

Code: Alles auswählen

adresse = results_update[1].find('div',{'data-testid':'property-address'}).find('a',{'data-testid':'property-card-link'}).get_text().split(',')
Zugriff Strasse

Code: Alles auswählen

adresse[0]
Zugriff region

Code: Alles auswählen

region = adresse[1],adresse[2]

Da ich aber nicht nur einen Eintrag habe möchte ich über eine Liste drüber gehen

da bekomm ich aber immer wieder Fehler, kann mir da vielleicht jemand helfen.

Code: Alles auswählen

region_liste = []
for result in results_update:
    # region

    adresse = results_update[0].find('div',{'data-testid':'property-address'}).find('a',{'data-testid':'property-card-link'}).get_text().split(',')
    region_liste.append(result.adresse[1])


vielen Dank nochmal für die Hilfe
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Rednaxelarekced,

Ohne die genaue Fehlermeldung und den kompletten Code zu sehen, kann man da nur raten.
Rednaxelarekced
User
Beiträge: 17
Registriert: Mittwoch 6. März 2019, 22:04

Code: Alles auswählen


from bs4 import BeautifulSoup
import requests
import pandas as pd

webseite = 'https://www.trulia.com/CA/San_Francisco/'

response = requests.get(webseite)

response.status_code
soup = BeautifulSoup(response.content, 'html.parser')

results = soup.find_all('li',{'class':'SearchResultsList__WideCell-b7y9ki-2'})
results_update = []

for r in results:
    if r.has_attr('data-testid'):
        results_update.append(r)
        
adresse = results_update[1].find('div',{'data-testid':'property-address'}).find('a',{'data-testid':'property-card-link'}).get_text().split(',')
adresse[0]

region = adresse[1],adresse[2]

print(region)


results_update[0].find('div',{'data-testid':'property-beds'}).get_text()
results_update[0].find('div',{'data-testid':'property-baths'}).get_text()
results_update[0].find('div',{'data-testid':'property-floorSpace'}).get_text()


region_liste = []


# For schleife
for result in results_update:
    # region

    adresse = results_update[0].find('div',{'data-testid':'property-address'}).find('a',{'data-testid':'property-card-link'}).get_text().split(',')
    region_liste.append(result.adresse[1])



hier ist der Fehler

Code: Alles auswählen

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-133-caaac4a44789> in <module>
     10 
     11     adresse = results_update[0].find('div',{'data-testid':'property-address'}).find('a',{'data-testid':'property-card-link'}).get_text().split(',')
---> 12     region_liste.append(result.adresse[1])
     13 

TypeError: 'NoneType' object is not subscriptable



Benutzeravatar
sparrow
User
Beiträge: 4535
Registriert: Freitag 17. April 2009, 10:28

result.adresse ist None

Code: Alles auswählen

>>> foo = None
>>> foo[0]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    foo[0]
TypeError: 'NoneType' object is not subscriptable
Ich habe mir deinen Code nicht näher angeschaut, aber ich finde das seltsam, dass du in der for-Schleife etwas an den Namen adresse bindest, das nicht mehr verwendest aber dafür result.adresse verwendest.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Rednaxelarekced,

Hier ist der funktionierende Code.
Ich habe an einigen Stellen Kommentare eingefügt.
Ich hoffe es ist soweit verständlich, sonst frag nochmal nach.

Code: Alles auswählen

from bs4 import BeautifulSoup
import requests
import pandas as pd # wird gar nicht genutzt

webseite = 'https://www.trulia.com/CA/San_Francisco/'

response = requests.get(webseite)

response.status_code # Diese Zeile hat keine Auswirkung
soup = BeautifulSoup(response.content, 'html.parser')

results = soup.find_all('li',{'class':'SearchResultsList__WideCell-b7y9ki-2'})
results_update = []

for r in results:
    if r.has_attr('data-testid'):
        results_update.append(r)

# 2. Addresse
adresse = results_update[1].find('div',{'data-testid':'property-address'}).find('a',{'data-testid':'property-card-link'}).get_text().split(',')

adresse[0] # Diese Zeile hat keine Auswirkung

region = adresse[1],adresse[2]

print(region)

# Diese Zeilen haben keine Auswirkung
results_update[0].find('div',{'data-testid':'property-beds'}).get_text()
results_update[0].find('div',{'data-testid':'property-baths'}).get_text()
results_update[0].find('div',{'data-testid':'property-floorSpace'}).get_text()


region_liste = [] # es ist eigentlich eine Liste für Straßen, daher ist der Name verwirrend
for result in results_update:
    # region

    # Beim interieren muss man im result nach der Adresse suchen
    adresse = result.find('div',{'data-testid':'property-address'}).find('a',{'data-testid':'property-card-link'}).get_text().split(',')

    # Straße ist index 0 nicht 1, die Straße ist ist das erste Element von des Tuples addresse
    region_liste.append(adresse[0])

print(region_liste)
Es scheint, das Ganze ist eine Baustelle, daher macht dein Code an einigen Stellen keinen Sinn.
Rednaxelarekced
User
Beiträge: 17
Registriert: Mittwoch 6. März 2019, 22:04

Hallo rogerb
Ich lerne gerade erst Python, deshalb vielen vielen Dank !
Lg rednaxelarekced
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Man kann übrigens auch direkt auf die Adressen im HTML-Code zugreifen:

Code: Alles auswählen

from bs4 import BeautifulSoup
import requests

response = requests.get("https://www.trulia.com/CA/San_Francisco/")
soup = BeautifulSoup(response.content, "html.parser")

for address_element in soup.find_all("div", {"data-testid": "property-address"}):
    print(address_element.text)
Rednaxelarekced
User
Beiträge: 17
Registriert: Mittwoch 6. März 2019, 22:04

Ich benötige nur "San Francisco, CA 94110" etc.

oder besser gesagt, zu Übungszwecken möchte ich einzelne Teile des Strings in eine Ergebnisliste speichern.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Das kann man erreichen indem man die Addresse zunächst in einzelne Teile zerlegt und die Leerzeichen jeweils an Anfang und Ende entfernt (mit strip()).
Das hattest du ja auch schon.
Ich verwende hier nur eine List-Comprehension weil es etwas kompakter ist.
Um Stadt, Staat und Zip-Code wieder in einen String zu vereinen nimmt man join()

Code: Alles auswählen

import pprint
from bs4 import BeautifulSoup
import requests

response = requests.get("https://www.trulia.com/CA/San_Francisco/")
soup = BeautifulSoup(response.content, "html.parser")

output_list = []
for address_element in soup.find_all("div", {"data-testid": "property-address"}):
    parts = [part.strip() for part in address_element.text.split(",")]
    output_list.append(", ".join(parts[1:]))

pprint.pprint(output_list)
Rednaxelarekced
User
Beiträge: 17
Registriert: Mittwoch 6. März 2019, 22:04

Super, genau das hat mir gefehlt.

Vielen lieben Dank !
Antworten