Seite 1 von 1
Schleife mit mehreren Versuchen
Verfasst: Mittwoch 22. Mai 2019, 12:29
von KosmoKramer
Hallo
Ich versuche ein Script zu schreiben in dem Daten von einer Immobiliensuchmaschine abgefragt werden und in einer .txt Datei gespeichert wird.
Da nicht alle Inserate vollständige Informationen haben, versuche ich das Script so aufzubauen, dass die einzelnen Variablen abgefragt werden und falls eine nicht im Quellcode der Seite vorhanden ist, zur nächsten gesprungen wird und das Script nicht abbricht.
Wie genau Programmiere ich diesen Ablauf?
Das war mein Ansatz bis jetzt:
Code: Alles auswählen
try:
Preis = Stelle im Quellcode
Stadtteil = Stelle im Quellcode
#Falls der Stadtteil nicht angegeben wurden ist gib mir einfach nur den Preis
except as Exception e:
Preis = Stelle im Quellcode
Re: Schleife mit mehreren Versuchen
Verfasst: Mittwoch 22. Mai 2019, 14:46
von __deets__
Exceptions sind dazu da, Code ab einem bestimmten Punkt abzubrechen. Was du suchst ist ein Weg etwas nur dann zu machen, wenn eine Bedingung zutrifft. Pro-Tipp: wenn das Wörtchen wenn nicht wär....
Re: Schleife mit mehreren Versuchen
Verfasst: Mittwoch 22. Mai 2019, 15:30
von Sirius3
@KosmoKramer: realer Code mit realen Beispielwerten hilft ungemein.
Du sprichst von Abbruch, aber wie passiert der Abbruch? Verursachst Du den explizit? Oder implizit?
Mit den von Dir gegebenen Informationen kann man nur sagen: sorge einfach dafür, dass es keinen Abbruch gibt.
Re: Schleife mit mehreren Versuchen
Verfasst: Donnerstag 23. Mai 2019, 07:57
von xXSkyWalkerXx1
1. Benutze "if" (Bezüglich "Pro-Tipp: wenn das Wörtchen wenn nicht wär...." - __deets__)
2. Was erhältst du, wenn "Stadtteil" kein Inhalt hat - None/"" /[] /{} oder was? Könntest nämlich dies ja vergleichen und, bevor dein Skript etwas in die Textdatei schreibt, gegebenfalls das Schreiben von "Stadtteil" überspringen.
Z.b:
Code: Alles auswählen
if Stadtteil != None: #vorhanden
#schreibe stadtteil
#schreibe preis
Wäre so meine Idee, aber deine Beschreibung lässt viele Fragen offen, daher kann ich nur vermuten, was du meinst. Ich weiß z.b. Nicht, ob du aus der Datei mehrmals die Werte für die Variablen ausliest.
Das ganze musst du zwar noch etwas vervollständigen, z.b mit der For-Schleife (vorher musst du den source_code erstmal lesen lassen), damit du alle Werte bekommst.
Re: Schleife mit mehreren Versuchen
Verfasst: Donnerstag 23. Mai 2019, 08:07
von sparrow
@Skywalker Das Beispiel in 2. ist unglücklich. Wenn der Preis sowieso geschrieben wird, muss den einfach außerhalb der Bedingung schreiben. Dann spart man sich den Else-Block.
Re: Schleife mit mehreren Versuchen
Verfasst: Donnerstag 23. Mai 2019, 08:07
von xXSkyWalkerXx1
Stimmt, hast Recht!
EDIT: Hab's im Post noch geändert.
Re: Schleife mit mehreren Versuchen
Verfasst: Donnerstag 20. Juni 2019, 08:33
von KosmoKramer
Hey vielen Dank für die Antworten. Ich hatte leider jetzt erst wieder Zeit mich daran zu setzten.
Das hier ist mein vollständiger Code:
Code: Alles auswählen
import requests
import json
from bs4 import BeautifulSoup as bs
import datetime as dt
import os
import re
import time
import urllib.request
from urllib.request import urlopen
import csv
linklist = ["https://www.immobilienscout24.de/Suche/S-2/Wohnung-Kauf/Nordrhein-Westfalen/Duesseldorf/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/true?enteredFrom=result_list", "https://www.immobilienscout24.de/Suche/S-2/P-2/Wohnung-Kauf/Nordrhein-Westfalen/Duesseldorf/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/true","https://www.immobilienscout24.de/Suche/S-2/P-3/Wohnung-Kauf/Nordrhein-Westfalen/Duesseldorf/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/true"]
for links in linklist:
res = requests.get(links)
soup = bs(res.content, 'lxml')
r = re.compile(r'resultListModel:(.*)')
data = soup.find('script', text=r).text
script = r.findall(data)[0].rstrip(',')
#resultListModel:
results = json.loads(script)
ids = [item['@id'] for item in results['searchResponseModel']['resultlist.resultlist']['resultlistEntries'][0]['resultlistEntry']]
print(ids)
data = json.dumps(ids)
houseinfo = {}
Flattyp = ()
csvData = [['id','purchasePrice','Spacesize','District','Flattyp','Flattypp','Rooms']]
def get_house_info (House):
for id in ids:
sourceCode = urllib.request.urlopen('https://www.immobilienscout24.de/expose/' + str(id)).read()
purchasePrice = str(sourceCode).split('"purchasePrice":')[1].split(',"geoCode"')[0]
Spacesize = str(sourceCode).split('"area":')[1].split('},"details"')[0]
District = str(sourceCode).split('"quarter":')[1].split('},')[0]
if Flattyp != str(sourceCode).split('"is24qa-typ grid-item three-fifths">')[1].split('</dd> </dl> <dl class')[0]:
Flattyp == "nicht vorhanden"
else:
Flattyp = str(sourceCode).split('"is24qa-typ grid-item three-fifths">')[1].split('</dd> </dl> <dl class')[0]
Rooms = str(sourceCode).split('is24qa-zimmer grid-item three-fifths"> ')[1].split(' </dd> </dl> <dl class=')[0]
parking_space = str(sourceCode).split('<dd class="is24qa-garage-stellplatz grid-item three-fifths">')[1].split('</dd> </dl>')[0]
if parking_space != str(sourceCode).split('<dd class="is24qa-garage-stellplatz grid-item three-fifths">')[1].split('</dd> </dl>')[0]:
parking_space = "nicht vorhanden"
else:
parking_space = str(sourceCode).split('<dd class="is24qa-garage-stellplatz grid-item three-fifths">')[1].split('</dd> </dl>')[0]
with open('fooneu23.txt', 'a') as csvfile:
cols = ['id', 'price', 'size', 'district', 'flattyp', 'rooms', 'parking_space','Flattypp']
dict_result = {'id': id, 'price': purchasePrice, 'size': Spacesize, 'district': District, 'flattyp': Flattyp, 'rooms': Rooms, 'parking_space':parking_space, 'Flattypp':Flattypp}
writer = csv.DictWriter(csvfile, fieldnames=cols)
writer.writeheader()
writer.writerow(dict_result)
csvfile.close()
get_house_info(ids)
Ich habe versucht das ganze jetzt so mit einem If-Statement zu lösen:
Bekomme dabei jedoch eine Fehlermeldung.
Code: Alles auswählen
if Flattyp != str(sourceCode).split('"is24qa-typ grid-item three-fifths">')[1].split('</dd> </dl> <dl class')[0]:
Flattyp == "nicht vorhanden"
else:
Flattyp = str(sourceCode).split('"is24qa-typ grid-item three-fifths">')[1].split('</dd> </dl> <dl class')[0]
Fehlermeldung:
"UnboundLocalError: local variable 'Flattyp' referenced before assignment"
Es wäre klasse wenn mir jemand weiterhelfen könnte.
Re: Schleife mit mehreren Versuchen
Verfasst: Donnerstag 20. Juni 2019, 10:44
von __blackjack__
@KosmoKramer: Welchen Wert hat denn `Flattyp` Deiner Meinung nach bevor dieses ``if`` das erste mal ausgeführt wird? Und wo wird der gesetzt? Ich sehe da nur ein `Flattyp` auf Modulebene was nichts mit dem lokalen Namen `Flattyp` in der Funktion zu tun hat.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Funktionen und Methoden sollten alles was sie ausser Konstanten benötigen als Argument(e) übergeben bekommen.
Du scheinst da HTML mit Zeichenkettenoperationen zu verarbeiten – das ist kaputt, das macht man nicht. Du hast doch sogar schon einen HTML-Parser eingebunden, dann nutze den auch.
Re: Schleife mit mehreren Versuchen
Verfasst: Donnerstag 20. Juni 2019, 11:04
von Sirius3
@KosmoKramer: Eingerückt wird mit vier Leerzeichen pro Ebene und nicht 1 oder 2 Tabs. Variablennamen werden nach Konvention klein_mit_unterstrich geschrieben.
Die Klasse BeautifulSoup sollte man nicht mit bs abkürzen.
datetime, os und time werden importiert aber nicht genutzt.
Warum benutzt Du urllib, wo doch schon requests verwendet wird?
In Zeile 19 verwendest Du findall statt search, obwohl Du nur das erste Element benutzt.
Die for-Schleife ist unsinnig, weil nur mit dem letzten Element etwas gemacht wird.
Bei Zeilen 25 - 28 werden drei Variablen definiert, die weder in noch außerhalb der for-Schleife benutzt werden.
`get_house_info` hat ein Argument `House` das nicht verwendet wird und `ids` wird benutzt, obwohl es kein Argument ist.
Hier wird urllib benutzt, obwohl Du an anderer Stelle requests benutzt. Strings setzt man nicht per + zusammen, sondern benutzt Stringformatierung. `sourceCode` ist bereits ein String, das immer wieder in einen String umzuwandeln, ist unsinnig.
HTML bearbeitet man nicht mit String-Funktionen, sondern, wie Du in der ersten for-Schleife schon machst, mit BeautifulSoup.
Daher möchte ich mich gar nicht erst durch die vielen splits arbeiten, die zum Teil auch doppelt gemacht werden. Besonders bei parking_space wird es lustig, da Du der Variable einen Wert zuweist, dann mit dem identischen Wert vergleichst und falls der tatsächlich immer noch gleich ist, der Variable nochmal diese Wert zuweist.
Es gibt ein Flattypp mit doppel-P, das wie ein Schreibfehler aussieht und nicht definiert ist.
Flattyp wird dagegen verwendet, bevor es definiert wird. Aber auch hier verstehe ich die if-Abfrage, wie auch bei parking_space schon, nicht.
Als erstes mußt Du also der ersten for-Schleife einen Sinn geben, oder entfernen, und die Ermittlung der IDs in eine Funktion packen. In der Funktion get_house_info urllib auf requests und das Stringgemetzel durch BeautifulSoup ersetzen.