Archiv verlassen und diese Seite im Standarddesign anzeigen : (PHP) - Crawler optimieren (Schneller!?)
Uranjitsu
14.08.2018, 17:57
Hallo zusammen,
hat jemand eine Idee, um den Crawler zu optimieren?
function get_data($url)
{
/* do some curl magic */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function get_match($regex, $content, $pos = 1)
{
/* do your job */
preg_match($regex, $content, $matches);
/* return our result */
return $matches[intval($pos)];
}
echo "Naruto-Tube Crawler Test<br />";
function pageSearch()
{
$html = file_get_contents('http://naruto-tube.org/boruto-episoden-streams'); //get the html returned from the following url
$pokemon_doc = new DOMDocument();
libxml_use_internal_errors(true); //disable libxml errors
if (!empty($html)) {
//if any html is actually returned
$pokemon_doc->loadHTML($html);
libxml_clear_errors(); //remove errors for yucky html
$pokemon_xpath = new DOMXPath($pokemon_doc);
//get all the h2's with an id
$pre_link = $pokemon_xpath->query('//tr/@onclick');
if ($pre_link->length > 0) {
foreach ($pre_link as $row) {
$search = array("window.location.href = '", "'");
$replace = array("", "");
$clean_link = str_replace($search, $replace, $row->nodeValue);
// Grab Name
$name = get_data("http://naruto-tube.org" . $clean_link);
$grabed_name = @get_match('/<td class="contentheading" width="100%">([^\"]*)<\/td>/', $name);
// Search Video URL
$search_vid_url = get_data("http://naruto-tube.org" . $clean_link);
$search_vid_url_found = @get_match('!var S1 = \'<iframe width="735" height="414" src="(.+)" frameborder="0" scrolling="no" allowfullscreen></iframe>\'!iUm', $search_vid_url);
// Grab Video File
$founded_vid_url = get_data($search_vid_url_found);
$grab_video = @get_match('!file: "(.+)",!iUm', $founded_vid_url);
$stream_file .= '<a href="' . $grab_video . '">' . $grabed_name . '</a><br />';
}
}
}
$array = array(
$stream_file,
);
return ($array);
}
$boruto = pageSearch();
echo $boruto[0];
Ich finde, er sucht (zu)lange!?
Kann auch an der Seite liegen, aber wnen jemand Optimierungsvorschläge hat, würde ich mich über Hilfe freuen.
LG
Aufs maximum optimieren und dann mit Threads arbeiten.
Uranjitsu
14.08.2018, 18:52
Richtig.
Wenn jemand dafür Ansätze hat, bin ich um das teilen ebenfalls sehr dankbar.
y0l0sw4gg3r
14.08.2018, 19:04
Hilfe zur Selbsthilfe: Hast du mal einen performance profiler damit beschäftigt? Wenn ein solcher fehlt einfach mal nen paar aktuelle DateTime jeweils vor und nach den einzelnen funktionsaufrufen speichern und anschließend auswerten. Somit weisst du anschließend, wo ggf. ein performance-engpass besteht. Das sollte die grundlage für weitere optimierungen sein.
Ich vermute, dass die teuersten aufrufe irgendwo im Laden der Webseiten liegt.
Eine generelle Frage: Benötigst du wirklich einen DOM und Regex? Mir scheinen alle deine Regex auch als XPath abbildbar zu sein.
Diese angesprochenen "Optimierungen" sind völlig egal.
Nur dein "get_data" muss asynchron gemacht werden oder du erstellst pro Iterationsschritt einen neuen Thread, der get_data aufruft.
Threads sind in hier in jeder Hinsicht wiedermal die schlechtere Wahl.
Ich denke mit ReactPHP's HTTPClient (https://reactphp.org/http-client/) sollte die asynchrone Variante gut lösbar sein.
y0l0sw4gg3r
15.08.2018, 11:28
@4nn8: Was macht einen Asynchronen aufruf denn schneller? Ist ein Asynchroner vorgang in PHP kein gesonderter Thread für das OS? Du bekommst den Callback vom Server nach seiner response - egal ob async oder nicht.
Ich möchte noch einmal betonen, dass es nicht sinnvoll ist optimierungen durchzuführen, wenn man nicht weiss, was konkret die Performance so schlecht macht.
Ohne diese Performance-Messungen (vor und nach der Optimierung) existiert kein erfolgsindikator.
Hinzufügen möchte ich auch noch, dass noch garnicht gesagt ist, dass das Script ein performance Problem hat - es kann durchaus der remote Server die Ursache für das Problem sein - oder die eigene Kiste.
Asynchron macht es nicht schneller, sondern sorgt dafür, dass deine HTTP-Requests in get_data gleichzeitig ausgeführt werden und nicht hintereinander.
In der jetzigen Foreach wird jedes mal gewartet, bis der eine HTTP-Aufruf fertig ist, damit die Schleife weiterlaufen kann.
Pro Iteration sind das also bestimmt acht Round-Trip-Times je nach Größe der Seite.
Bei einer Paketumlaufzeit von 40ms sind das schon 320ms. Und das ist der Best-Case würde ich sagen ^^
Wenn du es asynchron machst, dann läuft die Schleife sofort durch und im Hintergrund werden alle HTTP-Aufrufe gleichzeitig durchgeführt.
Umgesetzt wird es durch eine Event Loop (https://en.wikipedia.org/wiki/Event_loop) und läuft im selben Thread ab.
Uranjitsu
15.08.2018, 15:52
Danke @y0l0sw4gg3r und 4nn8 für die Infos:
Kann man mir eventuell anhand des obigen Codes ein Beispiel aufzeigen?
ToLinkTo
16.08.2018, 21:28
Hallo,
bevor du dich mit React beschäftigst solltest du die einfachste Lösung in Betracht ziehen. Einen multi curl handle zu nutzen.
Es gibt unendliche viele PHP Libs dafür: https://github.com/search?q=php+multi+curl
Da bei dir bereits Curl läuft sollte dies ohne großen Aufwand in dein Projekt zu integrieren sein.
Grüße
Uranjitsu
17.08.2018, 17:44
Offensichtlich rotieren die Links. Das Wrong IP ist nach einer gewissen Zeit wieder weg.
Kann mir jemand da was funktionierendes bauen? Natürlich entlohne ich das ganze auch, ich komme einfach nicht weiter.
Uranjitsu
21.08.2018, 16:56
Hallo zusammen,
Danke noch einmal an alle Beteildigten, die Hilfestellung angeboten haben.
Ich habe nun eine Möglichkeit gefunden, die Seiten schnell und unkompliziert zu durchsuchen:
!Allerdings ist das Wrong IP damit auch nicht gelöst: https://github.com/joshfraser/rolling-curl/blob/master/example.php
Diesen Code nutze ich:
<?php
function get_match($regex, $content, $pos = 1)
{
/* do your job */
preg_match($regex, $content, $matches);
/* return our result */
return $matches[intval($pos)];
}
require "RollingCurl.php";
if (isset($_GET['action'])) {
$action = $_GET['action'];
} else {
$action = "";
}
if ($action == "") {
$action = "intro";
}
if ($action == "intro") {
echo "<b>Episoden: </b> <a href=\"boruto.php?action=episoden\">boruto.php?action=episoden</a><br />";
echo "<b>Movies: </b> <a href=\"boruto.php?action=movies\">boruto.php?action=movies</a><br />";
}
/***************************
*
* EPISODEN
*
***************************/
if ($action == "episoden") {
$html = file_get_contents('http://naruto-tube.org/boruto-episoden-streams'); //get the html returned from the following url
$pokemon_doc = new DOMDocument();
libxml_use_internal_errors(true); //disable libxml errors
if (!empty($html)) {
//if any html is actually returned
$pokemon_doc->loadHTML($html);
libxml_clear_errors(); //remove errors for yucky html
$pokemon_xpath = new DOMXPath($pokemon_doc);
//get all the h2's with an id
$pre_link = $pokemon_xpath->query('//tr/@onclick');
if ($pre_link->length > 0) {
foreach ($pre_link as $row) {
$search = array("window.location.href = '", "'");
$replace = array("", "");
$clean_link = str_replace($search, $replace, $row->nodeValue);
$urls[] = "http://naruto-tube.org" . $clean_link; // Clan Link to array
}
}
}
// a function that will process the returned responses
function request_callback($response, $info)
{
// parse the page title out of the returned HTML
$embed = @get_match('/<iframe.*src="((https?|http):\/\/)?((www).)ani-stream.com\/([^\"]*)".*><\/iframe>/i', $response, 5);
$title = @get_match('/<td class="contentheading" width="100%">([^\"]*)<\/td>/', $response);
//print_r($info);
echo '<a href="boruto.php?action=grab-video&url=' . $embed . '">' . $title . '</a><br />';
}
// create a new RollingCurl object and pass it the name of your custom callback function
$rc = new RollingCurl("request_callback");
// the window size determines how many simultaneous requests to allow.
$rc->window_size = 20;
foreach ($urls as $url) {
// add each request to the RollingCurl object
$request = new RollingCurlRequest($url);
$request->options = array(CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)');
$rc->add($request);
}
$stream = substr($rc->execute(), 0, -1);
}
/***************************
*
* MOVIES
*
***************************/
if ($action == "movies") {
$html = file_get_contents('http://naruto-tube.org/boruto-movie-streams'); //get the html returned from the following url
$pokemon_doc = new DOMDocument();
libxml_use_internal_errors(true); //disable libxml errors
if (!empty($html)) {
//if any html is actually returned
$pokemon_doc->loadHTML($html);
libxml_clear_errors(); //remove errors for yucky html
$pokemon_xpath = new DOMXPath($pokemon_doc);
//get all the h2's with an id
$pre_link = $pokemon_xpath->query('//tr/@onclick');
if ($pre_link->length > 0) {
foreach ($pre_link as $row) {
$search = array("window.location.href = '", "'");
$replace = array("", "");
$clean_link = str_replace($search, $replace, $row->nodeValue);
$urls[] = "http://naruto-tube.org" . $clean_link; // Clan Link to array
}
}
}
// a function that will process the returned responses
function request_callback($response, $info)
{
// parse the page title out of the returned HTML
$embed = @get_match('/<iframe.*src="((https?|http):\/\/)?((www).)ani-stream.com\/([^\"]*)".*><\/iframe>/i', $response, 5);
$title = @get_match('/<td class="contentheading" width="100%">([^\"]*)<\/td>/', $response);
//print_r($info);
echo '<a href="boruto.php?action=grab-video&url=' . $embed . '">' . $title . '</a><br />';
}
// create a new RollingCurl object and pass it the name of your custom callback function
$rc = new RollingCurl("request_callback");
// the window size determines how many simultaneous requests to allow.
$rc->window_size = 20;
foreach ($urls as $url) {
// add each request to the RollingCurl object
$request = new RollingCurlRequest($url);
$request->options = array(CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)');
$rc->add($request);
}
$stream = substr($rc->execute(), 0, -1);
}
if ($action == "grab-video") {
if (isset($_GET['url'])) {
$url = "http://www.ani-stream.com/" . $_GET['url'];
} else {
$url = "FAIL";
}
// a function that will process the returned responses
function request_callback($response, $info)
{
// parse the page title out of the returned HTML
$video = @get_match('/file: "([^\"]*)",/', $response);
//print_r($info);
echo '<a href="' . $video . '">Stream starten</a>';
}
$rc = new RollingCurl("request_callback");
$rc->request($url);
$stream = substr($rc->execute(), 0, -1);
}
echo $stream;
Ich habe keine Ahnung, wie ich das nach Zeit auftretene WrongIP umgehen kann. Da ich zwischenzeitlich teste, generiere ich natürlich alleine von mir aus, sehr viele Anfragen. Eigentlich dachte ich, dass ich das mit der Class von GitHUB umgehen kann.
Ausserdem, kann mir jemand sagen, wie ich die Ausgabe sortiert geliefert bekomme? Die Links kommen zwar alle an, aber durcheinander :/
LG
badloader
21.08.2018, 19:07
Disclaimer: Nur halb qualifizierter Kommentar, da ich immer noch zu faul bin dein Script und deine Aufgabenstellung genau zu lesen.
Kannst du mir erklären was du mit "WrongIP" meinst? Ist das ein CURL error oder ein HTTP (Response) Error?
Umformuliert: Antwortet dir die Seite mit "WrongIP" oder sagt dir das dein Script?
Uranjitsu
22.08.2018, 17:24
Die Seite antwortet damit. Auch mal mit 404 nginx... Obwohl die Datei online ist.
Das grabbe ich:
<script>
var playerInstance = jwplayer('player');
function loadplayer(){
$('#video_thumb').hide();
$('#video_fdva').hide();
$('#video_player').show();
playerInstance.setup({
autostart: true,
file: "https://node04.ani-stream.com/d/qk5pofc4whfxuqe6sng2fpfntgd4daond3qol7hqhe4rjzpf6a nl6md7/video.mp4",
type: 'mp4',
height: window.innerHeight,
image: '//cdn.ani-stream.com/thumb/1gqzfnjpqhje.jpg',
startparam: 'start',
width: window.innerWidth,
abouttext:'ANI-STREAM Player - VIDEO ID: 1gqzfnjpqhje',
aboutlink: 'https://www.ani-stream.com/1gqzfnjpqhje',
logo: {
hide: true,
file: '//cdn.ani-stream.com/images/logo.png'
},
advertising: {
client: 'vast',
schedule: {
ads: {
offset: 'pre',
'tag': ['https://spl1.yumenetworks.com/yvp/20/1846kmCVgOTZ/secured_anistream_vpaid_as3.xml','https://spl1.yumenetworks.com/yvp/21/1846jDCeHjPH/secured_anistream_vpaid_html5.xml']
}
}
},
sharing: {
code: encodeURI('<iframe width="640" height="360" src="https://ani-stream.com/embed-1gqzfnjpqhje.html" frameborder="0" scrolling="no" allowfullscreen></iframe>'),
link: 'https://www.ani-stream.com/1gqzfnjpqhje'
},
});
playerInstance.on('adComplete', function(event){
ga('send', 'event', 'Ad Complete', event.tag, event.message);
});
playerInstance.on('adError', function(event){
ga('send', 'event', 'Ad Error', event.tag, event.message);
});
playerInstance.on('error', function(event){
ga('send', 'event', 'Media Error', 'Errors (4)', event.message);
});
playerInstance.on('ready', function(){
$(window).on('resize orientationChange', function(event) {
var width = $(window).width();
var height = $(window).height();
window.playerInstance.resize(width, height);
});
});
}
</script>
Dort ziehe ich mir die Datei:
file: "https://node04.ani-stream.com/d/qk5pofc4whfxuqe6sng2fpfntgd4daond3qol7hqhe4rjzpf6a nl6md7/video.mp4",
Das wäre die Seite: ANI-STREAM.COM - Naruto Shippuuden Movie 08 GER SUB by naruto-tube.mp4.mp4 (http://www.ani-stream.com/embed-1gqzfnjpqhje.html)
Selbst wenn ich Proxys verwende, passiert das gleiche.
Für eine Weile kann ich grabben und Videos schauen und dann taucht das "WrongIP" auf und selten ein erlogenes "404". Mit und ohne Proxy.
Wenn ich das Video aber dann im Player abspiele: Boruto Movie 1 GER SUB | Boruto: Naruto The Movie (http://naruto-tube.org/boruto-movie-1)
Geht das ohne Probleme... wo ich dann davon ausgehe, dass ich nicht gesperrt bzw. geblockt bin.
Muss ich eventuell einen Referrer mit übergeben, wie könnte diese aussehen?
Ich habe auch versucht die User-Agent als Google Bot zu tarnen, auch kein Erfolg.
LG
Also ich bekomme das Video-File, sofern ich die selbe IP nutze mit dem ich den File Not Found (http://www.ani-stream.com/embed-xxx.html) Link aufgerufen habe. User-Agent kann sich ändern. Referrer habe ich keinen gesetzt.
pythonfreak
22.08.2018, 19:02
Mal von einem anderen Server aus testen Uranjitsu , ob da der selbe Fehler auftritt? Oder mal mit weniger threads versuchen? ich hab das mal in python nachgebaut (ohne threads), kein wrong ip oder 404 Fehler, User-Agent immer von einem browser, also kein bot. https://pastebin.com/Xh2trmK1
Edit:
Das Video hab ich nicht abgespielt, nur die links ausgelesen...
Uranjitsu
23.08.2018, 03:48
@Nimbus, ich bekomme das File auch. Aber nach einiger Zeit, lässt es sich nicht mehr öffnen und es kommt WrongIP. Dein Link ist nicht erreichbar.
@pythonfreak, danke dafür. Die Variante ohne Threads, mit Threads... Etc. Für eine gewisse Zeit lässt sich das Video abspielen, aber irgendwann tritt dann dieses wrong IP auf.
@Nimbus, ich bekomme das File auch. Aber nach einiger Zeit, lässt es sich nicht mehr öffnen und es kommt WrongIP. Dein Link ist nicht erreichbar.
Ja gut. Hab ich fast schon vermutet.
Das soll vermutlich einfach so sein, damit keiner die Links weiterverwendet/weitergibt. Ist nicht unüblich :D
Welcher Link ist nicht erreichbar? Meinst du den Beispiellink bei dem die ID durch "XXX" ersetzt ist um allgemeiner zu bleiben?
Uranjitsu
23.08.2018, 10:43
Wenn diese Meldung erscheint , ist es aber weiterhin möglich mit dem hauseigenen Player das Video zu sehen. Daher meine ich, dass man eventuell etwas mit übergeben muss wie ein Referrer z.B
Edit: Ja, dein Link aus dem Beitrag. Habe nun auch gesehen ^^
Deren Player erzeugt gültige Links bzw. hat Zugriff auf gültige Links. Der alte Link dürfte wahrscheinlich dann unabhängig vom Aufruf ungültig sein.
Powered by vBulletin® Version 4.2.2 Copyright ©2026 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.