| PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Post your PHP questions here! |
 |
|

09-12-2010, 21:44
|
|
AKraisser
Registrierter Benutzer
|
|
Registriert seit: Sep 2010
Beiträge: 59
|
|
Einzelne Webseite auf einlesen und link prüfen
Hallo,
da ich noch nicht sehr fit bin in PHP brauche ich Hilfe um den richtigen Weg zu finden.
Möchte gerne ein script erstellen das mir eine angegebene URL auf Vorhandensein eines Link prüft und wenn gefunden den Status z.B. Online zurück gibt.
Würde die Seite so einlesen :
Code:
$seite = file_get_contents('http://www.xxx.de/xyz/test.php');
Dann ist der HTML-Inhalt in der Variable $seite.
Wie prüft man jetzt am besten den Inhalt der Variable. Es geht dabei auch um ressourcensparend zu arbeiten und möglichst die abfrage so schnell wie möglich zu gestalten.
Wie kann ich das am besten machen ?
Danke
|

10-12-2010, 07:06
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
Hallo,
wenn du ressourcensparend arbeiten willst, empfehle ich PHP: XMLReader - Manual zu nehmen. Wenn du es (aufgrund mangelnder Kenntnisse) einfach halten willst, nimm PHP: DOM - Manual (dafür gibt es massig Beispiele/Tutorials). Besonders hilfreich in diesem Falle: PHP: DOMDocument::getElementsByTagName - Manual
Gruß,
Amica
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt? 
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke! 
|

11-12-2010, 13:32
|
|
bmedia
Registrierter Benutzer
|
|
Registriert seit: Dec 2010
Beiträge: 37
|
|
|

12-12-2010, 14:08
|
|
AKraisser
Registrierter Benutzer
|
|
Registriert seit: Sep 2010
Beiträge: 59
|
|
Zitat:
Zitat von AmicaNoctis
|
Danke !
Habe jetzt eine Mischung aus DOM - und Xpath. Läuft aber werde mir noch XMLReader anschauen ob das nicht schneller ist.
Das größte Problem was ich noch habe das die hoster meistens nur 120 Sekunden Scriptlaufzeit erlauben und die Scripte viel länger laufen müssen.
Da weiß ich nicht wie ich das einfach lösen könnte?
|

12-12-2010, 16:47
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
Zitat:
Zitat von AKraisser
Das größte Problem was ich noch habe das die hoster meistens nur 120 Sekunden Scriptlaufzeit erlauben und die Scripte viel länger laufen müssen.
|
Sowas kann man nur ganz speziell auf eine bestimmte Aufgabe zuschneiden. Wenn da also Tipps dazu haben möchtest, musst du so detailliert wie möglich erklären, was du vorhast.
Generell kann man natürlich versuchen, zu optimieren und/oder längere Aufgaben mittels Sessions o. ä. in mehrere Anfragen aufteilen. AJAX ist auch eine immer öfter anzutreffende Möglichkeit, aufwändige Operationen in kleine Teilschritte zu zergliedern und sukzessive oder sogar quasiparallel mit mehreren Request-Response-Zyklen abzuarbeiten.
Wie gesagt, was davon im Endeffekt Sinn macht, hängt stark vom eigentlichen Problem ab.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt? 
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke! 
|

14-12-2010, 23:00
|
|
rei
Registrierter Benutzer
|
|
Registriert seit: Dec 2010
Beiträge: 15
|
|
validurl -> curl -> tidy -> simplexml -> statistik/rekursion
Hallo,
ich hab da mal einen miniCrawler gekippt
( www.neidl.net::spider
Das script hat komplett 18K filesize und braucht keine 2sec.)
und hier meine Tipps:
-> validurl
Prüf erstmal ob es auch eine sinnvolle URL ist
ftp://asdf.df/
https://asdf.df/grafik.gif
...
damit Dein "Robot" auch einen vernünftigen Anfang findet.
-> curl
Benutzt lieber gleich curl; das ist den Aufwand locker Wert.
z.b.: timeouts der URL erkennen, übergrosse "Dateien" abbrechen (es gibt auch 2MB HTML-Seiten  , oder PDFs hinter *.php), ...
-> tidy
Das verhindert, dass simplexml, DOM, ... vor den Kopf geschlagen werden.
Ist auch recht dankbar, aber manchmal bleibt von der URL-source auch nichts mehr über.
-> simplexml
Zum Finden Deiner Links in der URL-source.
Ist für Dich auch sehr dankbar, da intuitiv bedienbar.
Check mal: xpath
PS.: Es gibt nicht nur <a>-ancer um HTML-Seitne zu verlinken.
vgl.: <frame>,<maps>,...
Nun hast Du eigentlich schon Deine Links von der Seite.
-> statistik/rekursion
Was Du mit den Links anfängst ist natürlich Deine Sache. 
rekursion: weiterverfolgen... vgl: -> validurl
statistik: was auch immer Dich interessiert.
Je "fremder" die Seiten sind, die Du analysierst desto mehr musst Du damit rechnen, dass irgendwas kommt:
-domains nicht bekannt
(wwww.asdf.df wegen TippFehler, domain abgemeldet)
-server ist inaktiv
-Verzeichnisschutz
-cycle redirects
-Port 8080, https, ftp Links/URLs
-Grafik,PDF,Datei anstatt HTTP-source ( http://www.asdf.df/d.php)
-fehlerhafter HTTP-source, char-set
-fehlerhafte ancer
...
Und hier kann bereits cURL gute Dienste leisten, natürlich musst Du bei Fehlern "angemessen" reagieren.
P.S.: bei den file_get_content() gibt es glaub ich auch einen $context;
die sind meist recht gut, aber schlecht dokumentiert.
|

15-12-2010, 11:23
|
|
AKraisser
Registrierter Benutzer
|
|
Registriert seit: Sep 2010
Beiträge: 59
|
|
Danke für deine Antwort rei!
Bis jetzt habe ich folgendes:
Code:
$ziel_url = 'http://www.kfzversicherungrechner.eu/';
$backlink_url = 'http://www.versicherung-online-24.com/';
$userAgent = 'Googlebot/2.1 (http://www.googlebot.com/bot.html)';
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_URL,$backlink_url);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$html= curl_exec($ch);
if (!$html) {
echo "<br />cURL error number:" .curl_errno($ch);
echo "<br />cURL error:" . curl_error($ch);
exit;
}
// parse der html in ein DOMdocument
$dom = new DOMDocument();
@$dom->loadHTML($html);
// die Links rausholen
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");
for ($i = 0; $i < $hrefs->length; $i++) {
$href = $hrefs->item($i);
$url = $href->getAttribute('href');
if ($ziel_url == $url) {
$ankertext = $href->nodeValue;
$rel = $href->getAttribute('rel');
$followCheck = 'FOLLOW';
if ($rel == 'nofollow') {
// Backlink vorhanden mit NOFOLLOW setzen : online , NOFOLLOW , datum -> lastDate
$followCheck = 'NOFOLLOW';
}
// Backlink normal vorhanden setzen : online , FOLLOW , datum -> lastDate
mysql_query("UPDATE backlink SET backlinkStatus='online', backlinkFollow='$followCheck', lastDate='$datum'
WHERE zielUrl = '$url'") or die(mysql_error());
}
} // Ende for schleife
Funktioniert auch relativ gut. Aber ist noch eine Menge Arbeit bis es sauber läuft.
Einige Seiten funktionieren z.B noch nicht wenn diese mit einem redirect weitergeleitet sind usw.
Es läuft auch relativ schnell nur weiß ich nicht ob es so ne gute Idee ist gleich in die Datenbank zu schreiben oder nicht besser wäre zuerst in einen File oder array und dann wenn alle Seiten abgefragt sind erst in die Datenbank!? Das sind die sachen die mir abgehen an wissen.
Habe für das oben ja schon zwei Tage gebraucht mich überall einzulesen :-)
Habe auch versucht mit dem XMLReader der ja die schnellste Möglichkeit wäre zu arbeiten. Leider konnte ich nichts finden wie man auf eine html seite damit zugreift. Glaube das geht gar nicht!?
Gruß
Andy
|

15-12-2010, 15:14
|
|
rei
Registrierter Benutzer
|
|
Registriert seit: Dec 2010
Beiträge: 15
|
|
Zitat:
Zitat von AKraisser
Danke für deine Antwort rei!
....
Es läuft auch relativ schnell nur weiß ich nicht ob es so ne gute Idee ist gleich in die Datenbank zu schreiben oder nicht besser wäre zuerst in einen File oder array und dann wenn alle Seiten abgefragt sind erst in die Datenbank!? Das sind die sachen die mir abgehen an wissen.
...
Gruß
Andy
|
Normalerweise wäre ein multi-insert in DB schon besser, aber in diesem Fall
ist es vielleicht besser den aktuellen Stand sofort zu speichern, da Dein Script sich u.U. vorzeitig abbricht und viele Daten dann 'halbfertig' sind. z.B.: Externe Daten bringen Dein Script in Peinlichkeiten, nicht abgefangene Fehler, timeouts an allen möglichen Stellen...
P.S.:
-Das Speichern in eine Datei ist auch eine Form von persitenter Datenhaltung.
-mit den ganzen redirects und Co. gibt es alles mögliche...
|

17-12-2010, 13:57
|
|
AKraisser
Registrierter Benutzer
|
|
Registriert seit: Sep 2010
Beiträge: 59
|
|
cUrl und geblockte Seiten
Mein Script funktioniert leider nur zum Teil. Also ca. 70% gehen. Die anderen blocken leider das script. Ich lese die Seite ja mit cUrl aus! Kann oder muss ich hier noch Änderungen machen damit es aussieht als würde ein User die Seite aufrufen und das Script nicht mehr geblockt wird?
Momentaner Code:
Code:
function get_url( $backlink_url, $javascript_loop = 0 ) //
{
$backlink_url = str_replace( "&", "&", urldecode(trim($backlink_url)) );
//$cookie = tempnam ("/tmp", "CURLCOOKIE");
$ch = curl_init();
curl_setopt( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1" );
curl_setopt( $ch, CURLOPT_URL, $backlink_url );
//curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookie );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_ENCODING, "" );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
//curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 );
curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );
//curl_setopt($ch, CURLOPT_REFERER, "http://www.greenits.at");
// curl_setopt($ch, CURLOPT_VERBOSE, 1);
//curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true);
//curl_setopt($ch, CURLOPT_PROXY, "bioproxy.info:80");
//curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt( $ch, CURLOPT_MAXREDIRS, 5 );
$content = curl_exec( $ch );
$response = curl_getinfo( $ch );
curl_close ( $ch );
if ($response['http_code'] == 301 || $response['http_code'] == 302)
{
ini_set("user_agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1");
if ( $headers = get_headers($response['url']) )
{
foreach( $headers as $value )
{
if ( substr( strtolower($value), 0, 9 ) == "location:" )
return get_url( trim( substr( $value, 9, strlen($value) ) ) );
}
}
}
if ( ( preg_match("/>[[:space:]]+window\.location\.replace\('(.*)'\)/i", $content, $value) || preg_match("/>[[:space:]]+window\.location\=\"(.*)\"/i", $content, $value) ) &&
$javascript_loop < 5
)
{
return get_url( $value[1], $javascript_loop+1 );
}
else
{
return array( $content, $response );
}
}
|

17-12-2010, 14:06
|
wahsaga
 Moderator
|
|
Registriert seit: Sep 2001
Beiträge: 24.486
|
|
Zitat:
Zitat von AKraisser
Also ca. 70% gehen. Die anderen blocken leider das script.
|
Bitte lerne langsam mal, vernünftige Problembeschreibungen zu verfassen!
Mit der zitierten Aussage lässt sich ähnlich wenig anfangen, wie mit einem „funzt nich“.
__________________
I don't believe in rebirth. Actually, I never did in my whole lives.
|

17-12-2010, 14:33
|
|
AKraisser
Registrierter Benutzer
|
|
Registriert seit: Sep 2010
Beiträge: 59
|
|
Zitat:
Zitat von wahsaga
Bitte lerne langsam mal, vernünftige Problembeschreibungen zu verfassen!
Mit der zitierten Aussage lässt sich ähnlich wenig anfangen, wie mit einem „funzt nich“.
|
OK Sorry.
Also mein Script soll mittels cUrl auf eine vorgegebene Seite zugreifen. Aus dieser Seite alle Links raus holen und mit einem Link von mir vergleichen.
Also eine einfache Backlinkkontrolle.
Jetzt stellt sich das Problem das manche Seiten aber mein Script blocken.
Da ich mit cUrl auf die Seiten zugreife muss ich wahrscheinlich hier noch was ändern. Vielleicht noch den Header mit senden oder? Die frage ist wie erkennen die Seiten das es sich nicht um einen Menschen handelt und wie muss ich das richtig anstellen mit cUrl ?
Danke
|

17-12-2010, 17:49
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
Es gibt mehrere Möglichkeiten, zu erahnen (niemals mit 100%iger Sicherheit), ob eine Anfrage von einer Privatperson oder einem Programm kommt. Zunächst mal die offensichtlichsten Sachen: Automatische Anfragen können nicht mit JavaScript umgehen, sie senden (meistens) so wenige Headerzeilen wie möglich, sie Akzeptieren (meist) keine Cookies und damit auch keine Sessions. Dann kann man noch prüfen, ob die IP-Adresse des Clients rückwärts auflösbar ist. Eine dynamische IP-Adresse ist fast immer eine Privatperson, eine statische mit hoher Sicherheit ein Webserver eines großen Hosters, also vermutlich ein Script.
Hilft das erstmal als grober Überblick?
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt? 
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke! 
Geändert von AmicaNoctis (17-12-2010 um 18:08 Uhr)
|

17-12-2010, 18:27
|
|
AKraisser
Registrierter Benutzer
|
|
Registriert seit: Sep 2010
Beiträge: 59
|
|
Zitat:
Zitat von AmicaNoctis
Es gibt mehrere Möglichkeiten, zu erahnen (niemals mit 100%iger Sicherheit), ob eine Anfrage von einer Privatperson oder einem Programm kommt. Zunächst mal die offensichtlichsten Sachen: Automatische Anfragen können nicht mit JavaScript umgehen, sie senden (meistens) so wenige Headerzeilen wie möglich, sie Akzeptieren (meist) keine Cookies und damit auch keine Sessions. Dann kann man noch prüfen, ob die IP-Adresse des Clients rückwärts auflösbar ist. Eine dynamische IP-Adresse ist fast immer eine Privatperson, eine statische mit hoher Sicherheit ein Webserver eines großen Hosters, also vermutlich ein Script.
Hilft das erstmal als grober Überblick?
|
Das heißt ich versuch so viel wie möglich Headerinformationen mitzusenden. Cookies kann man auch bei cUrl aktivieren und ich lasse es ja hier lokal laufen auf meinem Rechner der hat immer eine dynamische IP.
Das wäre dann das optimale was ich mit cUrl rausholen kann.!?
|

17-12-2010, 20:45
|
unset
 Moderator
|
|
Registriert seit: Jan 2007
Ort: Düsseldorf
Beiträge: 3.778
|
|
Ich würde ja erst einmal den User-Agent anpassen …*und zwar auf einen "normalen" Browser.
|

17-12-2010, 20:58
|
|
AKraisser
Registrierter Benutzer
|
|
Registriert seit: Sep 2010
Beiträge: 59
|
|
Zitat:
Zitat von unset
Ich würde ja erst einmal den User-Agent anpassen …*und zwar auf einen "normalen" Browser.
|
Bin schon etwas weiter gekommen!
Jetzt blocken die Seiten nicht mehr aber irgendwas läuft noch schief.
Er schreibt mir oft "offline" in die Datenbank obwohl die Bedingung if ($ziel_url == $url) erfüllt ist.
KORRIGIERE !! Er springt mir nur 8 mal von 32 in die if ($ziel_url == $url) schleife! Die frage ist warum
Anbei mal der ganze Code:
Code:
<div class="content">
<?php
$start1 = microtime(true);
$datum = date("Y-m-d");
function get_url( $backlink_url ) //
{
$curl = curl_init();
// Setup headers - I used the same headers from Firefox version 2.0.0.6
// below was split up because php.net said the line was too long. :/
$header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
$header[] = "Cache-Control: max-age=0";
$header[] = "Connection: keep-alive";
$header[] = "Keep-Alive: 300";
$header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
$header[] = "Accept-Language: en-us,en;q=0.5";
$header[] = "Pragma: "; // browsers keep this blank.
$cookie = tempnam ("/tmp", "CURLCOOKIE");
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie );
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'Googlebot/2.1 (+http://www.google.com/bot.html)');
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_REFERER, 'http://www.google.com');
curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$html = curl_exec($curl); // execute the curl command
curl_close($curl); // close the connection
return $html; // and finally, return $html
}
do { // beginn der do while schleife
//$backlink_url = "http://www.infos-zum-thema.de/der-stromrechner-vergleich-findet-guenstige-stromangebote.htm";
//$ziel_url = "http://www.stromrechner-24.de/stromrechner-vergleich/";
$backlink_url = $row_allLinkCheck['backlinkUrl']; // backlink aus Datenbank holen
$ziel_url = $row_allLinkCheck['zielUrl']; // Ziel Seite aus Datenbank holen
$html = get_url($backlink_url); // funktion aufrufen cUrl
//$html = $text[0]; // $text enthält Inhalt der Seite
//$fp = fopen ( 'test.txt', 'w' );
//fwrite ( $fp, $html );
//fclose ( $fp );
//echo $text[1]; ??
// parse the html into a DOMDocument
$dom = new DOMDocument();
@$dom->loadHTML($html);
// grab all the on the page
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");
//echo $hrefs;
// Link Checken ob online und follow und Datum setzen
$followCheck = '';
$linkCheck = 'offline';
for ($i = 0; $i < $hrefs->length; $i++) {
$href = $hrefs->item($i);
$url = $href->getAttribute('href');
$ziel_url = trim ($ziel_url, " \t\n\r\0\x0B/");
$ziel_url = stripslashes($ziel_url);
$url = trim ($url, " \t\n\r\0\x0B/");
$url = stripslashes($url);
//echo $backlink_url .":<br/>";
//echo $ziel_url ."<br/>";
echo $url . "<br/><br/><br/><br/>";
if ($ziel_url == $url) {
$followCheck = 'FOLLOW';
$linkCheck = 'online';
$ankertext = $href->nodeValue;
$rel = $href->getAttribute('rel');
if ($rel == 'nofollow') {
$followCheck = 'NOFOLLOW';
}
} // Ende if
} // Ende for schleife
// Status in die Datenbank eintragen nach Durchlauf der for schleife
mysql_query("UPDATE backlink SET backlinkStatus='$linkCheck', backlinkFollow='$followCheck', lastDate='$datum'
WHERE backlinkUrl = '$backlink_url'") or die(mysql_error());
} while ($row_allLinkCheck = mysql_fetch_assoc($allLinkCheck)); // do while schleife
echo microtime(true)-$start1.' Sekunden verbraucht';
?>
<!-- end .content --></div>
Geändert von AKraisser (17-12-2010 um 21:05 Uhr)
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|