Request Object in Schleife bleibt gleich

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
Gisi
User
Beiträge: 15
Registriert: Sonntag 13. Mai 2007, 17:28

Hi,

ich möchte in einer for Schleife bei jedem Durchlauf ein Request Object neu anlegen. Es soll jedes mal ein Link kreiert werden, bestehend aus einem festen Anfang und dann ein get Anhang in Form von "&bla=blabla..."

das Dictionary, das den Anhang liefert, wird jedes mal neu kreiert, das funktioniert. Jedoch nimmt er ab dem zweiten Durchlauf jedes mal das Object, das beim ersten Durchlauf kreiert wurde, obwohl eben das Dictionary neu gemacht wurde. Hier mal der Codeausschnitt:

Code: Alles auswählen

reslist = []
for seite in range(anzahlSeiten):
	new_criteria = {"_form": "search", 
								"sr_model": "arnage",
								"sr_make": "3100",
								"top": str((seite+1) * 20 -19)}
															
	add_to_link = urllib.urlencode(new_criteria)
	newlink = urllib2.Request("http://mobile.de/cgi-bin/index_cgi.pl?" + add_to_link)
	newlink.add_header("User-Agent", "Mozilla/5.0")
	jedeSeite = urllib2.urlopen(newlink).read()
	
	linklist = re.findall(
       "[/]cgi[-]bin[/]da[.]pl[?]bereich[=]pkw[&]top[=]\d+[&]id[=]\d+",
	jedeSeite)
	
	for link in linklist:
		reslist.append(link)

ausgabe.close()
Ich sitz jetzt seit heut morgen an dem Teil und dem Rest des Programms. Bitte entschuldigt, wenn ich mich nicht ganz klar ausgedrückt habe, wo das Problem ist. Mir raucht der Kopf. Bitte fragt nach, wenn was unklar ist.

Wie krieg ich Python jetzt dazu, beim zweiten Durchlauf eben das Dictionary anzuhängen, das auch beim zweiten Durchlauf kreiert wurde?

Gruß aus Heidelberg,

Gisi
BlackJack

Ich hab's mal auf das wesentlich zusammengestrichen und lauffähig gemacht:

Code: Alles auswählen

import urllib

anzahlSeiten = 5

for seite in range(anzahlSeiten): 
    new_criteria = {"_form": "search",
                    "sr_model": "arnage",
                    "sr_make": "3100",
                    "top": str((seite+1) * 20 -19)}

    add_to_link = urllib.urlencode(new_criteria) 
    print add_to_link
Ausgabe:

Code: Alles auswählen

_form=search&top=1&sr_model=arnage&sr_make=3100
_form=search&top=21&sr_model=arnage&sr_make=3100
_form=search&top=41&sr_model=arnage&sr_make=3100
_form=search&top=61&sr_model=arnage&sr_make=3100
_form=search&top=81&sr_model=arnage&sr_make=3100
Was genau gefällt Dir daran jetzt nicht, bzw. wo ist das Problem? Für mich sieht das okay aus.

Die Formel für `top` kann man etwas einfacher schreiben: ``str(seite * 20 + 1)``
Gisi
User
Beiträge: 15
Registriert: Sonntag 13. Mai 2007, 17:28

Genau das meinte ich, das Dictionary, also "add_to_link" wird jedes mal neu gemacht. Genau so, wie ich das haben will. Das funktioniert.

Nur wenn ich bei jedem Durchlauf den String, den mir "jedeSeite" zurückgibt, ausgebe, erhalte ich 4 mal die gleiche Ausgabe, nämlich die, die beim ersten Durchlauf erzeugt wird. Und nicht 4 verschiedene, obwohl doch jedes mal "add_to_link" neu gemacht wird. Verstanden, was das Problem ist?
BlackJack

Okay, das ganze etwas erweitert:

Code: Alles auswählen

import urllib
import urllib2

anzahlSeiten = 3

test = list()
for seite in range(anzahlSeiten): 
    new_criteria = {"_form": "search",
                    "sr_model": "arnage",
                    "sr_make": "3100",
                    "top": str((seite+1) * 20 -19)}

    add_to_link = urllib.urlencode(new_criteria) 
    print add_to_link
    newlink = urllib2.Request("http://mobile.de/cgi-bin/index_cgi.pl?" + add_to_link) 
    newlink.add_header("User-Agent", "Mozilla/5.0") 
    jedeSeite = urllib2.urlopen(newlink).read() 
    test.append(jedeSeite)

print test[0] == test[1]
print test[1] == test[2]
print test[0] == test[2]
Ausgabe:

Code: Alles auswählen

_form=search&top=1&sr_model=arnage&sr_make=3100
_form=search&top=21&sr_model=arnage&sr_make=3100
_form=search&top=41&sr_model=arnage&sr_make=3100
False
False
False
Alle drei Seiten sind unterschiedlich. Ich sehe das Problem immer noch nicht.
Gisi
User
Beiträge: 15
Registriert: Sonntag 13. Mai 2007, 17:28

Hm, mal meine Version ausführlicher bzw komplett:

Code: Alles auswählen

import urllib2
import urllib
import re

search_criteria = {"_form": "search",
	  	   "sr_model": "arnage",
	  	   "sr_make": "3100"}

add_to_url = urllib.urlencode(search_criteria)
ausgabe = file("out.txt", "w")

url = urllib2.Request("http://mobile.de/cgi-bin/index_cgi.pl?"+
		      add_to_url)
url.add_header("User-Agent", "Mozilla/5.0")


# seite1 ist der komplette Quelltext der ersten Seite der Suchergebnisse,
# der zurueckgegeben wird, wenn man nach einem VW als Modell und "Polo" 
# sucht. Diese Werte sind oben bei search_criteria frei waehlbar, 
# "sr_make" siehe Quelltext.

seite1 = urllib2.urlopen(url).read()


# die Anzahl der Seiten wird benoetigt, weil jede Seite nur 20 Autos 
# darstellt. Es muessen aber alle Autos untersucht werden, auch auf 
# Seite 42. 

anzahlSeiten = int(re.sub("smallorange\"[>]von\s", "",
									 re.search("smallorange\"[>]von\s\d+", seite1).group()))
									 
print "es gibt " + str(anzahlSeiten) + " Seiten." + "\n"


# linklist holt sich die 20 Links aus der jeweiligen Seite raus, die zu den 
# 20 Detailansichten fuehren.

reslist = []
for seite in range(anzahlSeiten):
	new_criteria = {"_form": "search", 
								"sr_model": "arnage",
								"sr_make": "3100",
								"top": str((seite+1) * 20 -19)}
	add_to_link = urllib.urlencode(new_criteria)
	newlink = urllib2.Request("http://mobile.de/cgi-bin/index_cgi.pl?" + add_to_link)
	newlink.add_header("User-Agent", "Mozilla/5.0")
	jedeSeite = urllib2.urlopen(newlink).read()
	ausgabe.write(jedeSeite)
	
	linklist = re.findall(
       "[/]cgi[-]bin[/]da[.]pl[?]bereich[=]pkw[&]top[=]\d+[&]id[=]\d+",
	jedeSeite)
	
	for link in linklist:
		reslist.append(link)

ausgabe.close()
Wenn ich mir jetzt hier die output.txt ansehe, steht da 4 mal das gleiche drin. :(
BlackJack

Wie hast Du das überprüft? Also ich sehe das nicht auf den ersten Blick auf 4 komplette HTML-Seiten, insgesamt *13000 Zeilen*, die nacheinander in einer Datei stehen.

Wenn ich wieder den Test im Programm mache, kommt auch wieder heraus, dass alle 4 Seiten unterschiedlich sind.
Gisi
User
Beiträge: 15
Registriert: Sonntag 13. Mai 2007, 17:28

Das sind 4 Seiten mit jeweils 20 gelisteten Autos. Seite 1 fängt irgendwo bei 40.000 € an, das 20. Auto liegt bei 99.000 €. Auf Seite 2 beginnt also das nächst teurere Auto bei 110.000 € usw, denke das ist klar. Wenn ich jetzt aber in meiner output.txt nach "40.000" suche, finde ich das genau 4 mal. Die Preise, die im Original auf Seite 2, 3 oder 4 vorkommen, werden gar nicht gefunden.
Gisi
User
Beiträge: 15
Registriert: Sonntag 13. Mai 2007, 17:28

Ich raff das nicht. Habe ich meine Quelltext Liste mit den 4 Elementen angelegt und gebe diese per print aus, werden richtigerweise 4 verschiedene ausgegeben. Passt.

Mach ich allerdings

Code: Alles auswählen

for code in reslist:
    ausgabe.write(code)
wird 4 mal der gleiche Quelltext geschrieben. Sag mal spinn ich?
BlackJack

Kann ich auch nicht nachvollziehen. Wo steht denn diese Schleife bei Dir?

Und Du darfst bei den Links nicht nur nach der `id` schauen, sondern musst die Kombination aus `top` und `id` vergleichen.
Gisi
User
Beiträge: 15
Registriert: Sonntag 13. Mai 2007, 17:28

Ok, jetzt weiß ich wo das Prloblem liegt: Die Links, die ich mir über das Dictionary und den festen Anfang generiere, sind schuld.

Code: Alles auswählen

_form=search&top=1&sr_model=arnage&sr_make=3100
_form=search&top=21&sr_model=arnage&sr_make=3100
_form=search&top=41&sr_model=arnage&sr_make=3100
_form=search&top=61&sr_model=arnage&sr_make=3100 
wenn ich die an das "http://mobile..." hänge, steht bei jedem Link zwar oben:

"1 bis 20 von 64 gefundenen Fahrzeugen
21 bis 40 von 64 gefundenen Fahrzeugen
41 bis 60 von 64 gefundenen Fahrzeugen
61 bis 64 von 64 gefundenen Fahrzeugen"

Aber die Autos, die darunter gelistet werden, sind jedes mal die von Seite 1, also Fahrzeug 1 bis 20. Hat das was mit deinem letzten Hinweis
Und Du darfst bei den Links nicht nur nach der `id` schauen, sondern musst die Kombination aus `top` und `id` vergleichen.
zu tun? Andere Lösungsvorschläge, wie ich mir die richtigen Links basteln kann?
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Bei mir geht die Seite mobile.de nicht sonst hätte ich es mir mal angesehen.
Allgemeiner Tipp: Schau das du deine Links mal im Browser zum laufen bekommst. Wen sie dort schon nicht das gewünschte Ergebniss liefern wird es auch Python nicht tun.

lgherby
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Jap, es liegt nicht daran, dass dein Code falsch ist, sodern das die Links, die er produziert, falsch sind. Wie herby schon sagte, wenn du die erzeugten Links mal in den Browser eingibst, erhälst du auch immer die erste Seite, wobei bei den anderen dann 'seite 2' angezeigt wird, der Inhalt aber immernoch der gleiche ist.
Finde erstmal die richtigen Links, bevor du sie dynamisch erzeugst.

Gruß, jj
Gisi
User
Beiträge: 15
Registriert: Sonntag 13. Mai 2007, 17:28

So, nach langem Kampf gegen mobile kann ich die Links nun generieren. Ich hol mir zuerst die erste Ergebnisseite und von da per regular expression den Link, der zur Seite 2 führt. Der besteht aus jede Menge komischer Zahlen, Zeichen und Buchstaben am Anfang, die nun als Basislink dienen, an den nur noch das "top = 21" oder "top = 41" hingehängt wird.
Damit funktionierts! :)

Weiter gehts nun mit dem Extrahieren der jeweils 20 Links auf jeder Seite, die zu den Detailansichten der Autos führen. Aber das hatte ich schonmal gecoded, dürfte nicht weiter schwer sein. Hoffe ich...
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Das Ding mit den vielen Zahlen und Buchstaben wird eine "SessionID" sein.

guckst du http://de.wikipedia.org/wiki/SessionID ;)

lg herby
Antworten