Geizhals Shopping-Cart

Inhaltsverzeichnis

 

1. Vorwort Inhalt

Manchmal wundert man sich. Da gibt’s so einfache und nützliche Webseiten im Internet, die uns das tägliche Leben erleichtern. Viele kleine Helferlein, die uns in der digitalen und auch realen Welt den Weg weisen.

In der heutigen Ausgabe spreche ich von Preisvergleichsseiten im Internet. Eingetippt wird ein Produktname und nach kurzer Zeit erscheint eine Liste aller anbietenden Händler, mit Versandkosten und Gebühren und allem drum und dran gleich mit dabei. Die Liste läßt sich nach Preisen aufsteigend sortieren und fertig ist im Prinzip meine Bestellung; ich nehme natürlich den obersten.

2. A small bump in the road… Inhalt

Winziges Manko: Was denn, wenn ich aus einer Sparte mehrere verschiedene Produkte bestellen möchte? Vielleicht, um einen ganzen PC selbst zusammenzustellen oder mein nächstes Bike für den Sommer? Fazit heute, das schon Stefan Raab  mit seinen Tele-Tubbie-Figuren herausfand: ooooch, göht nicht.

Welch geniale Funktion wäre denn diese: Ich rüste in den Preisvergleich einen Warenkorb nach. Die Artikel, die ich bestellen möchte, kommen dort hinein, und das System ermittelt mir den aktuellen Gesamtpreis aller Anbieter, die die Artikel liefern oder zumindest im Angebot haben. Idealerweise werden die Versandkosten auch gleich verglichen.

Das wäre mal’n Dingen: eine nützliche Seite, die noch nützlicher wird.

Nun gut, Geizhals kann das nicht, wir legen wie gewöhnlich selbst Hand an.

3. …well, let’s get to work! Inhalt

Besagte Schwierigkeit läßt sich einfach mit etwas programmatischem Geschick lösen. Wir konzentrieren uns auf die Plattform Geizhals.at, die mit zu den am einfasten zu bedienenden gehört. Es ist zwar kein Eye-Candy, aber hey, unserem Programm wird das wurscht sein. Außerdem läßt sich der HTML-Code so besser parsen.

3.1 Aufgabenstellung Inhalt

Womit wir beim nächsten Punkt, nämlich dem Konzeptionellen, angelangt sind. Unser Programm muß folgende Aufgaben erfüllen:

  1. Entgegennehmen der fraglichen Produkte von Geizhals
  2. Abfragen der Händler und Preise für die Produkte
  3. Herausfiltern der Händler, die alle Produkte liefern
  4. Addieren zu Gesamtpreis pro Händler
  5. Ausgeben der sortierten Händlerliste, der billigste zuerst.

3.2 Technisch gesehen Inhalt

Lösen werden wir das Ganze mit einem kleinen Script in der Programmiersprache Python (Version 2.7.1, nicht mehr die aktuelle), da diese einen extrem guten SGML-Parser besitzt, der mit der Erweiterung BeautifulSoup wunderbar einfach angesprochen werden kann und auch dreckigen HTML-Code noch relativ robust verarbeitet. Wir parsen also die Webseite von Geizhals und fischen und die gewünschten Info’s, indem wir einen Webseitenbesuch simulieren.

4. And done. Inhalt

Das folgende Listing zeigt das fertige Python-Script. Zur Ausführung sind ein paar Schritte erforderlich:

  1. Man lade sich Python 2.7.1 herunter und installiere es in ein beliebiges Verzeichnis auf dem Computer.
  2. Man erstelle auf seinem Desktop oder /home ein Unterverzeichnis.
  3. Dort hinein kopiere man das Script von unten in eine neue Date, z.B. „gh.py“.
  4. Man lade sich BeautifulSoup, neueste Version, herunter und kopiere es ebenfalls dorthinein.
  5. Dann bearbeite man die Textdatei und trage die URLs der Artikel auf Geizhals oben in das Listing ein. Möchte man nur Händler, die den Artikel auch vorrätig („grünes Versandkostenfeld“) haben, kann man das mit dem Zusatz „?v=l“ bewerkstelligen, die komplette URL lautet dann etwa „http://geizhals.at/deutschland/a591090.html?v=l“.
  6. Abschließend rufe man das bearbeitete Script mit Python auf, z.B. durch Eingeben „C:\Program Files\Python\python.exe gh.py“ auf der Kommandozeile.
Fertiges Python Script
# -*- coding: utf-8 -*-

# Imports
from BeautifulSoup import BeautifulSoup;
import urllib2;

# URLs zu den Artikeln
artikelUrls = [
	'http://geizhals.at/deutschland/a591090.html', #MB
	'http://geizhals.at/deutschland/a586747.html', #GRAKA
	'http://geizhals.at/deutschland/a580331.html', #CPU
	'http://geizhals.at/deutschland/a572113.html', #RAM
	#'http://geizhals.at/deutschland/a586960.html', #HD
	#'http://geizhals.at/deutschland/a569031.html'  #NT
];

merchantOffers   = {};
merchantArticles = {};
merchantTotals   = {};

# Geizhals Shopping Cart...
print ""
print("****************");
print("Geizhals Shooper");
print("****************");
print ""

for artikelUrl in artikelUrls:
	try:
		opener = urllib2.build_opener()
		opener.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11')]
		response = opener.open(artikelUrl)
		page = response.read();
	except:
		print "Sorry, URL: "+ artikelUrl +" could not be opened."
		continue;

	soup = BeautifulSoup(page);

	# Artikelid parsen
	id = artikelUrl.split('/')[4].split('.')[0];

	# Artikelnamen parsen
	h1   = soup.h1;
	artikelName = h1.span.text[0:40];
	merchantArticles[id] = artikelName;
	print id + ': '+ artikelName;
	print "*****************";

	# Händler und Preis suchen
	merchants = soup.findAll('tr', { "class":["t1", "t2"] } )
	for merchant in merchants:
		if merchant.get("class") != 't1' and merchant.get("class") != 't2': continue;

		# Preis bestimmen
		mPreis = float(merchant.td.span.text.replace(',','.').replace('-','0'));

		# Händlernamen bestimmen
		tmp    = merchant.findAll('a')
		if tmp[0].img:
			# Aha, großes Bild. Händlername aus Titel laden
			mName = tmp[0].img['title'];
		else:
			mName = tmp[0].text;

		# Händlerkey bestimmen
		tmp    = merchant.findAll('div', {"class":"gh_hl1"});
		mKey   = tmp[0].a["href"].split("=")[1].split("&")[0];

		print mName.ljust(25) +": ",
		print mPreis

		if not mName in merchantOffers:
			merchantOffers[mName] = {};
		merchantOffers[mName][id] = mPreis;
	print "--------------------";
	print ""

# Ok, Grabbing finished. Jetzt Preisberechnung...
# Wir schmeissen alle weg, die nicht alles liefern können
for merchant in merchantOffers.keys():
	total = 0.0;
	if len(merchantOffers[merchant]) < len(artikelUrls):
		#print merchant, ": kann nicht alles liefern."
		continue
	preisDict = merchantOffers[merchant];

	for artikel in merchantArticles.keys():
		total = total + preisDict.get(artikel);
	total = round (total*100)
	merchantTotals[total] = merchant

# und sortieren
sortdict = merchantTotals.keys()
sortdict.sort()

print ""
print "##############################"
print "### Ausgabe"
print "##############################"
print ""
print "Artikel"
print "-------"
for artikel in merchantArticles.keys():
	print " - "+artikel+": "+ merchantArticles[artikel]
print ""
print "Anbieter"
print "--------"
for total in sortdict:
	merchant = merchantTotals[total]
	print " * "+ merchant.ljust(25) + "%5.2f" % (total/100)

Bislang keine Kommentare vorhanden.

Einen Kommentar hinterlassen