"We are back" « oc.at

PHP Hilfe

s4c 26.09.2008 - 09:13 1845 16
Posts

s4c

input overrun
Avatar
Registered: Nov 2003
Location: near to vienna
Posts: 1308
Hallo!

Ich bin gerade daran mein PHP-Wissen aufzufrissen und arbeite momentan an einem kleinen content grabber der mir den Inhalt dann in eine Datenbank speichern soll.

Konkret will ich von einem URL die Bilder und natürlich den Namen des Bildes abspeichern. Am besten sogar lokal oder/und in dem Verzeichnis des PHP-Files.

Also bisher hab ich diesen Code gebastelt...

Code: PHP
<?php {
$domnam = "http://www.eineseite.com/";
$replvar = "ProdID="; $url = file_get_contents("http://www.eineseite.com/Search/Default.aspx?SortBy=LatestRelease");
$erste_linie = strpos($url, $replvar);
$zweite_linie = strpos($url, $replvar, $erste_linie+1);
$dritte_linie = strpos($url, $replvar, $zweite_linie+1);
$vierte_linie = strpos($url, $replvar, $dritte_linie+1);
$funfte_linie = strpos($url, $replvar, $vierte_linie+1);
$linkliste = substr($url, $erste_linie);
$imgsooncom = str_ireplace("image-placeholder.gif","#", $linkliste);
$sauber = str_ireplace("src=\"/", "src=\"".$domnam, $linkliste);
echo strip_tags(iconv("UTF-8", "ISO-8859-1", $sauber), "<img><br>");
}
?>

Jetzt ist aber mein Problem das ich auf PHP.net keinen Befehl finde mit Passagen von einem String auslesen kann..
Wozu? Ich brauch eine Variable "ProdID=xy123" und eben auch "ProdImg=URLdesBildes" womit ich dann eine SQL-Datenbank befüllen möchte. Ahja und wenn der URL des Bildes "palceholder.gif" ist, soll er keinen Eintrag in die SQLdb machen, weder mit der ProdID, noch sonst irgendwie...

Weiters sollen die Bilder abgespeichert werden. Lokal wird denk ich nicht gehn, aber zumindest am Webspace abzuspeichern wäre schon ein super Fortschritt.

Wenn in meinem Code etwas unschlüssig oder überflüssig ist, bitte sagen

Vielleicht kann mir der ein oder andere Spezialist weiterhelfen :)
Danke
Bearbeitet von s4c am 26.09.2008, 09:15

jives

And the science gets done
Avatar
Registered: Sep 2001
Location: Baden
Posts: 3548
Ich hab den Post ehrlich gesagt nur überflogen, weil ich gerade am Sprung bin, aber schau dir mal http://at.php.net/preg_split, http://at.php.net/preg_grep und Konsorten, http://at.php.net/manual/en/function.strstr.php und http://at.php.net/manual/en/function.explode.php an.

Ich glaube dein Problem könnte vor allem mit RegEx elegant zu lösen sein.

Wenn du mit lokal abspeichern meinst, dass du Files am HTTP-Client ablegen willst, so ist PHP der falsche Weg dafür. Files am Server abzulegen ist aber natürlich problemlos möglich.
Bearbeitet von jives am 26.09.2008, 10:02

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Du holst dir den Code von der Seite und suchst nach einem <img>-Tag liest den Rest bist zum </img>-Tag und lädtst (ggf. Seitenurl +) Bildurl. Wenn du auf deinem "Lokalen" Rechner, wie du es nennst - einen Fileserver oder eine Datenbank einrichtest und ein entsprechendes Port-Forwarding einrichtest, spricht auch nix dagegen, die Bilder auf diesem Rechner zu speichern.
Ach ja, das erste_linie, zweite_linie wird warscheinlich ein wenig Fad, dazu gibts Schleifen ;)

Medice

Intensivlaie
Avatar
Registered: Mar 2003
Location: irc.euirc.net - ..
Posts: 1967
Zitat von Obermotz
Du holst dir den Code von der Seite und suchst nach einem <img>-Tag liest den Rest bist zum </img>-Tag [...]

Das funktioniert aber nur wenn die Zielseite entsprechend gebaut ist - ich bin nicht mehr ganz am laufenden aber bestimmte htmls kommen ja mit einem alleinigen <img...> aus

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Hätt ich noch nie gesehen und wär imho auch nicht html-konform..

COLOSSUS

Administrator
GNUltra
Avatar
Registered: Dec 2000
Location: ~
Posts: 12208
Kommt auf die DTD an - aber das ist ziemlich egal, denn "in the wild" kommt das sehr wohl vor. <img> wird in der Regel nicht (HTML4 und darunter) bzw. implizit (XHTML1.0 und darueber) geschlossen. Aber das ist auch gar nicht weiter wichtig; eine einfache RegEx wie z. B. /<img.*?src=['"](.*?)['"]/ sollte das einzig wirklich Interessante, den URL zur Bilddatei naemlich, schon fetchen koennen.

Jede vernuenftige Programmiersprache - und vermutlich sogar PHP! - bietet allerdings Tokenizer/Parser fuer SGML/XML (und damit auch HTML und XHTML), mit der man das ganz einfach machen koennen sollte.

s4c

input overrun
Avatar
Registered: Nov 2003
Location: near to vienna
Posts: 1308
Also soll ich mir das mal mit RegExpresions anschaun, ob man sowas verwenden kann... Wär super wenn ich das irgendwie hinbekomm, dann spar ich mir nämlich so einen blöden grabber

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Regular Expressions wollen auch gelernt sein ;)
Ich liebe das Thema (i..i..iiirroo ach jetzt fällt mir das Wort nicht mehr ein).

Hilfe gibts hier:
http://www.regular-expressions.info/tutorial.html

jives

And the science gets done
Avatar
Registered: Sep 2001
Location: Baden
Posts: 3548
Zitat von COLOSSUS
Jede vernuenftige Programmiersprache - und vermutlich sogar PHP! - bietet allerdings Tokenizer/Parser fuer SGML/XML (und damit auch HTML und XHTML), mit der man das ganz einfach machen koennen sollte.
Gute Idee :)

http://at2.php.net/manual/en/refs.xml.php

s4c

input overrun
Avatar
Registered: Nov 2003
Location: near to vienna
Posts: 1308
danke vielmals für die vielen antworten.
hoffentlich bin ich weit genug um diese dinge auch anwenden zu können..

Lizardking

Big d00d
Avatar
Registered: Nov 2004
Location: sogined
Posts: 167
Zitat von Obermotz
Hätt ich noch nie gesehen und wär imho auch nicht html-konform..

also nach XHTML gibts eine ganze Reihe Tags, die kein schließendes solches benötigen ;)

zB
<input />
<img />

allerdings sollten diese mit Slash vor der ">" beendet werden - zB. auch <br />

nur als Anmerkung

onTopic: würde ich mir einfach den Substring von
<img bis >
holen und dann wiederum von
src=" bis "

hth

// jegliche Art/Kombination von String-Funktionen sind auf jeden Fall um Häuser schneller als Regex - ist in diesem Fall imho auch ned erforderlich.
Bearbeitet von Lizardking am 30.09.2008, 10:16

s4c

input overrun
Avatar
Registered: Nov 2003
Location: near to vienna
Posts: 1308
Zitat von Lizardking
onT
Was heisst das?
Und mit welchem Befehl kann ich mir den String vo <img bis > und von src=" bis " holen?
Schön wärs ja, darauf bin ich ja aus :)
Das könnte ich nämlich dann ganz easy in die DB schreiben.

Das Problem ist ja auch das dich den gesamten Quelltext nach mehreren Stellen mit diesen Tags durchgraben muß. Ich weiss keine Position und gar nix, ich könnte höchstens die Zeilen in der sie (theoretisch) vorkommen sollten einschränken. Wäre glaub ich 210 bis 72000 oder so..
Bearbeitet von s4c am 30.09.2008, 08:57

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
http://www.weberdev.com/get_example-1817.html

Bittesehr, ein bisschen modifiziert und du hast deine Lösung..

Lizardking

Big d00d
Avatar
Registered: Nov 2004
Location: sogined
Posts: 167
so, ist jetzt sehr quick n' dirty in wenigen minuten gepfuscht - gibt auch keine kontrolle, ob die gesuchte property innerhalb des tags vorkommt - bei <img> kann man aber mal davon ausgehen, dass ein src-wert angegeben ist ;)
die oben gepostete variante ist ev. eleganter - schneller wahrscheinlich nicht, da dort jedes Tag einzeln nochmal als array explodet wird - performance test wär mal interessant ..

hth

Code: PHP
<?
	
	// zu durchsuchende Datei
	$file = "test.html";
	
	// Tag Start
	$tagStart = '<img';
	
	// Eigenschaft
	$property = 'src';
	
	$imageTags = array();
	$images = array();

	// Datei einlesen
	$content = file_get_contents($file);
	$pointer = 0;
	
	// Start- und Endpositionen aller gewünschten Tags filtern
	while($pointer < strlen($content)) {
		$nextImageTag = stripos($content,$tagStart,$pointer);
		if($nextImageTag === false) {
			break;
		}
		$pointer = $nextImageTag + strlen($tagStart);
		$imageTags[] = $nextImageTag;
	}
	
	$pointer = 0;
	
	// Substrings der Properties filtern
	foreach($imageTags as $img) {
		$valueStart = stripos($content,$property,$img) + strlen($property) + 2;
		// Property unter doppeöten Hochkommas
		if(substr($content,$valueStart -1,1) == '"') {
			$valueEnd = stripos($content,'"',$valueStart);
			$nextImage = substr($content,$valueStart,($valueEnd - $valueStart));
		}
		else {
			$valueEnd = stripos($content,"'",$valueStart);
			$nextImage = substr($content,$valueStart,($valueEnd - $valueStart));
		}
		$images[] = $nextImage;
	}
	
	// Array $images nach Belieben weiterverarbeiten
	
?>

// "stripos" ist erst ab php5 verfügbar btw.

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Hier ein Script basierend auf Regex.:

Code: PHP
$str = file_get_contents("http://www.overclockers.at");

# extract src-links from images
$hits = array();
preg_match_all("/<img[^\>]+?src=\"(.*?)\".*?\/?\>/si", $str, $hits);
$hits = array_unique($hits[1]);
sort($hits);
print_r($hits);

# extract src-links from images, skip those that start with https?
$hits = array();
preg_match_all("/<img[^\>]+?src=\"((?!http\:\/\/|https\:\/\/).*?)\".*?\/?\>/si", $str, $hits);
$hits = array_unique($hits[1]);
sort($hits);
print_r($hits);
ich hoffe das is weitestgehend selbsterklärend :)
Mit tokenizer bist du da wesentlich langsamer unterwegs übrigens, regex sind extrem schnell in PHP, und dass man die return values vom tokenizer erstmal in PHP dann noch weiter behandeln müsste (während der regex ein praktisches array liefert und dieses in native code erstellt) spielt dabei keine kleine Rolle ;)


Grüße vom watcha.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz