[PHP] RegEx funktioniert nicht wie gewünscht

h0mpf

Neu angemeldet
Registriert
27 Nov. 2013
Beiträge
9
Hallo zusammen,

das ist das erste Mal, dass ich mich mit regulären Ausdrücken auseinandersetze und so langsam tut mir die Rübe weh.

Ich möchte für ein Kundenprojekt die Anzahl der Rezensionen für bestimmte Produkte auf Amazon.de im Auge behalten und bei einer neuen Rezension eine E-Mail schicken. Folgende Zeilen habe ich mir bei zusammengeklaut und dachte mir, dass ich die Zeile einfach anpassen könnte. Pustekuchen, seit einer Stunde fuckel ich nun schon und es mag einfach nicht hinhauen. :o

Hier am Beispiel von Battlefield 4:

[src=php]
$spock = "http://www.amazon.de/Battlefield-Deluxe-Edition-Exklusiv-Amazon/dp/B00C1XQGW0/";
$kirk = file_get_contents("AMZ.txt");
$enterprise = file_get_contents($spock);
preg_match('/">(.*?)(Kundenrezensionen<\/a>)/i', $enterprise, $pille);
echo $pille[2];
if ($pille[2]!=$kirk)
{
mail("beliebige@mail.tld", "Neue Kundenrezension auf Amazon", ("Aktuelle Anzahl bei: ".$pille[2]." Produkt: ".$spock), "From: mumpitz <beliebige@mail.tld>");
file_put_contents("AMZ.txt",$pille[2]);
}
[/src]

Das Wort Kundenrezensionen kommt an, aber die Anzahl der Rezensionen bekomme ich einfach nicht abgegriffen.

Habt ihr eine Idee, wo es haken könnte?

Danke im Voraus
h0mpf
 
Das Problem wird sein, dass du über $pille[2] auf die zweite erfassende Gruppe deines Ausdrucks zugreifst. Dein Ausdruck enthält zwei erfassende Gruppen, (.*?) und (Kundenrezensionen<\/a>), und du möchtest wohl eher die erste auslesen (tatsächlich könntest du die zweite auch entfernen und statt (Kundenrezensionen<\/a>) das Literal Kundenrezensionen<\/a> verwenden). Dies ist in deinem Code über $pille[1] möglich.
 
  • Thread Starter Thread Starter
  • #3
Logisch, hätte ich auch selbst drauf kommen können. :m Danke für den Hinweis!

Unschön ist allerdings, dass der ja in diesem Fall etwas mehr ausliest/ausgibt als gewünscht. Könnte man den RegEx auch so anpassen, dass der tatsächlich nur die Zahl und das Wort Kundenrezension ausgibt? Im Quelltext kommt das in dieser Kombination zweimal vor, ich würde nur die erste Erwähung benötigen.

Folgendermaßen habe ich es schon versucht, allerdings gibt er dann gar nichts zurück so dass ich denke, dass das ist einfach falsch ist.

[src=php]
preg_match('/^[0-9]{3} Kundenrezensionen$/i', $enterprise, $pille;
[/src]
 
[src=php]preg_match('/>(\d+) Kundenrezensionen<\/a>/i', $enterprise, $pille);[/src]

schreibt bei mir folgendes Array in $pille:

Code:
Expand Collapse Copy
Array
(
    [0] => >312 Kundenrezensionen</a>
    [1] => 312
)
 
  • Thread Starter Thread Starter
  • #5
Danke, epiphora! Das funktioniert super. :T

Ich glaube, ich werde mir mal entsprechende Lektüre aneignen, was reguläre Ausdrücke betrifft. Das wird mit Sicherheit nicht das letzte Mal sein, dass ich mich damit auseinandersetzen werden.
 
Nennst du deine Variablen ernsthaft nach Dingen aus dem Star Trek Universum? Könnte bei längerem Code dermaßen zu Verwirrung führen...

Ich nenne die ja immer gerne $iNumberOfReviews oder $sReviewString
 
  • Thread Starter Thread Starter
  • #7
Hi phre4k!

Nein, ich benenne meine Variablen generell anders. Wie eingangs erwähnt, hatte ich mich nur an diesem Beispiel orientiert was den RegEx anging und alles andere erstmal außer Acht gelassen:

Ich kenne ehrlich gesagt nicht mal den Unterschied zwischen Star Wars und Star Trek. Steinigt mich! :p
 
Vielleicht solltest du PHP lieber mal "from scratch" lernen. Habe festgestellt, dass Herumbasteln an Codefragmenten nicht sehr häufig zu gewünschten Ergebnissen führt.
 
  • Thread Starter Thread Starter
  • #9
Hallo, werte ngb-Gemeinschaft!

Leider muss ich diesen Thread nochmal ausgraben, da ich eine weiterführende Frage zu meinem Verständnis dazu habe.

Den folgenden Code verwende ich derzeit immer noch mehr oder weniger erfolgreich, muss diesen aber auch immer wieder mal für derzeit circa 15 Produkte angleichen (z. B. dann, wenn Amazon am Quelltext werkelt.). Problem an der Sache ist, dass ich pro Produkt eine Datei mit dem Script und dazu eine separate TXT-Datei anlegen muss. Ist es möglich, für mehrere Produkte nur eine PHP-Datei zu verwenden und dieser zu sagen, dass die Anzahl der Rezensionen von Produkt X in diese Datei, und die Anzahl der Bewertungen von Produkt Y in die andere Datei gehören?

foreach hörte ich bereits und las es schon nach, aber wie ich dem foreach dann die richtige Datei dem richtigen Produkt zuordne, hat sich mir leider noch nicht erschlossen. Produkt-Links in ein Array stecken klappt schon mal. Aber dann? Oder ist für mein vorhaben dann doch eine DB notwendig?

Wie immer gilt: keine vorgekaute Lösung notwendig, Hinweise auf entsprechende Seiten im PHP-Handbuch o. Ä. würden mir genügen. :)

Vorab dankt
h0mpf

Das derzeit werkelnde Script pro Produkt:
[src=php]<?php
$spock = "http://www.amazon.de/gp/product/B017O0L0V6/"; // Amazon Produkt-Link

$kirk = file_get_contents("mcAMZ.txt");
$enterprise = file_get_contents($spock);
preg_match('/>(\d+) Kundenrezensionen<\/span>/i', $enterprise, $pille);
echo $pille[1];
if ($pille[1]!=$kirk)
{
mail("hinz@kunz.xxx", "Neue Kundenrezension fuer BO3 auf Amazon", ("Aktuelle Rezensionen: ".$pille[1]." Produkt: ".$spock), "From: Amazon Bot <amzbot@kunz.xxx>");
file_put_contents("mcAMZ.txt",$pille[1]);
}
?>[/src]
 
Hallo h0mpf,

erst einmal: deine Variablen sind immer noch schlecht benannt. Bitte ändere das: der Code ist grauenvoll zu lesen.
Nein eine Datenbank benötigst du bei der Größenordnung (15 Produkte) nicht. Wenn du dich aber mit Datenbanken beschäftigen willst, kannst du eine einsetzen. Beim Programmieren gibt es meist mehr wie eine richtige Lösung. Hier wäre es aber schon ein wenig "mit Kanonen auf Spatzen" und mehr als Lernübung interessant.

Statt eine Datei pro Produkt zu erstellen solltest du dir überlegen alle Daten zusammen in eine Datei zu schreiben. Ein denkbares Format, da es sich mit PHP sehr einfach verarbeiten lässt, ist :
[src='JSON']{
"Computerspiel" : {
"url" : "amazon.de/kauf/8791cpspl",
"count" : 2
},
"Rasierapperat" : {
"url" : "amazon.de/kauf/2342rsappt",
"count" : 10
}
}[/src]

Wie bisher kannst du mit "file_get_contents" den Inhalt der Datei in einen String lesen, mit machst du aus diesem String ein . In dem Array änderst du dann die Werte für "count" und am Ende des Scripts wandelst du das Array mit json_encode wieder in einen String um und speicherst ihn mit file_put_contents wieder in die Datei zurück.

Verwendest du beim encode die Option JSON_PRETTY_PRINT ist die Datei auch für Menschen gut lesbar und du kannst neue Produkte dort sehr einfach einfügen, die dann verarbeitet werden.

Zwischen Lesen und Schreiben dieser Datei steht dann eine foreach Schleife (Also Dateizugriff nur am Anfang und Ende, nicht in jedem Schleifendurchlauf). Diese iteriert über das Array, sodass du in jedem Durchlauf je einen Key (z.B. "Rasierapperat") und einen Value (das Array ["url" => "amazon.de/kauf/2342rsappt", "count" => 10] ) hast.


Viel Spaß beim Basteln. Und immer dran denken: copy-pasta ist nur erlaubt, wenn man den Code auch versteht ;-)
Dieser Befehl macht jedes PHP Script 99% schneller, indem es die Datei von der Festplatte in den RAM verlegt!
PHP:
Expand Collapse Copy
unlink(__FILE__);
 
Zuletzt bearbeitet:
Zurück
Oben