Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]file_get_contents OPYMALIZACJA kodu. Strasznie długie ładownie.
Forum PHP.pl > Forum > Przedszkole
kielich
WItam,
Napisałem klasę, lecz dane pobierne są ze sklepu intenetowego. FIRMA => części => rodzaj_cześci => szczegóły towaru. Informacje wyszukują się idealnie. Przy "ostatnim etapie" - wyciąganie ceny produktu. Skrpty straaaasznie muli , ponad 5min co składnia mnie do nacisnięcia "ESC" sad.gif . Proszę o pomoc

  1. <?php
  2.  
  3. class Klocki{
  4.  
  5. const wzorzec_links = '#<li><a.*href=\"([^\"]*)\".*>([^\"]*)<\/a><\/li>#';
  6. const wzorzec_price = '#<span itemprop="price">([^\"]*)</span>#';
  7. const wzorzec_name = '#<span itemprop="name">([^\"]*)</span>#';
  8. private $linksAll = array();
  9.  
  10.  
  11.  
  12. private function getData() {
  13. $output = file_get_contents('link');
  14. preg_match_all(self::wzorzec_links, $output, $links);
  15.  
  16. return $links[1];
  17. }
  18.  
  19. private function parseData() {
  20. foreach(Klocki::getData() as $linkMore){
  21. preg_match_all(self::wzorzec_links, file_get_contents($linkMore), $links);
  22. foreach($links[1] as $linksMore){
  23. preg_match_all(self::wzorzec_links, file_get_contents($linksMore), $links);
  24. foreach($links[1] as $link){
  25. $linksAll[] = $link;
  26. }
  27. }
  28. }
  29. return $linksAll;
  30. }
  31.  
  32. public function getInfo(){
  33. if(Klocki::parseData() == true){
  34. foreach(Klocki::parseData() as $link){
  35. $outputs = file_get_contents($link);
  36. preg_match(self::wzorzec_price, $outputs, $price);
  37. preg_match(self::wzorzec_name, $outputs, $name);
  38. }
  39. }
  40. }
  41. }
  42.  
  43. Klocki::getInfo();
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52. ?>
jaslanin
podrzuć jakieś dane cobyśmy mogli sobie po testować bez pisania sobie wszystkiego z palca, bo nie każdemu się będzie chciało + jaki chcesz mieć dla tego output, jaki cel osiagnąć
kielich
  1. private function getData() {
  2. $output = file_get_contents('http://www.123drukuj.pl/Tusze-do-drukarek-p1.html');
  3. preg_match_all(self::wzorzec_links, $output, $links);
  4.  
  5. return $links[1];
  6. }


Reszta bez zmian. Po wywołaniu print_r(Klocki::parseData()); - oczywiście zmienić private na public , dostaje ładne linki i pózniej w getInfo() w foreach , chciałem wyswietlić cene. Lecz strasznie długo ładuje :/
!*!
To co podałeś jest bez sensu. A jak chcesz optymalizacji, to pobierz źródło raz, zapisz je w zmiennej i na niej operuj, a jak już za pomocą jednego wyrażenia pobierzesz dane, to tak jak wyżej, zapisz w zmiennej i na nich operuj, a nie robisz pętle w pętli dla pętli i to z file_get_content.
kielich
No dobrze ale pętli i tak się nie pozbędę. Muszę jakoś obrobić te dane. ? Może jakiś przykład mógłbym prosić ?

Tutaj nie mam jednego źródła - ta sama strona. Tylko "skaczę" po linkach - więc muszę pobierać nową treść stron.
!*!
Obróbka istniejącej zmiennej, to nie to samo co obróbka danych które pobieram za każdym razem.
kielich
ALe ja przechodzę z linku na link. mając tablice linków ponad(200linków) to muszę "poskakać" - po kazdym i wyciągnąć cenę
!*!
Nie rozumiem problemu. Mam link A, pobieram jego źródło w celu sprawdzenia czy są linki do strony B, jak są, zapisuję je do tablicy. Jak już mam wszystkie linki, sprawdzam czy znajduje się w nich nazwa i cena, jak tak, uzupełniam tablice. Koniec. Na moje oko jest to jedna pętla, max 2.
kielich
FIRMA => części => rodzaj_cześci => szczegóły towaru - jak widać mam link A wchodzi dalej mam B jak mamy dalej C i dopiero produkt więc jak możesz mieć 1 pętle ? smile.gif
artuross
Cytat(!*! @ 2.04.2013, 14:06:38 ) *
Nie rozumiem problemu. Mam link A, pobieram jego źródło w celu sprawdzenia czy są linki do strony B, jak są, zapisuję je do tablicy. Jak już mam wszystkie linki, sprawdzam czy znajduje się w nich nazwa i cena, jak tak, uzupełniam tablice. Koniec. Na moje oko jest to jedna pętla, max 2.


On ma racje, w jego przypadku na podstronach znajduja sie kolejne podstrony, wiec nie wystarczy wejsc w jeden link, zeby uzyskac cene. Trzeba wejsc na kolejny i kolejny.

Kielich, czemu sie dziwisz, ze trwa to 5 minut? Skoro polaczenie z tyloma stronami troche trwa, dodatkowo to musi byc obrobione za pomoca regexp, ktory tez do najszybszych nie nalezy. Moze powienienes sprawdzic jaki zakres bitow potrzebujesz pobrac? Mniej szukania, dzialalby ciut szybciej, aczkolwiek nadal jest to z 500 stron lub cos w tym stylu.
kielich
Dokładnie jest to 5160 linków , przerobiłem że mam w jednej funkcji w drugiej przerabiam a w trzeciej wyświetlam. Lecz pozbycie się pętli jest NIEMOŻLIWE.
Bardzo proszę o jakąś pomoc.
artuross
Czlowieku zrozum, ze tego nie przyspieszysz! Nie masz infrastruktury Google w domu, zeby obsluzyc taka ilosc zapytan na raz. To wszystko trwa, z reszta serwery tego sklepu tez nie maja, a i one musza wygenerowac zawartosc.
!*!
Jest różnica między 200 a 5160, taka tyci.

Cytat
Czlowieku zrozum, ze tego nie przyspieszysz! Nie masz infrastruktury Google w domu, zeby obsluzyc taka ilosc zapytan na raz. To wszystko trwa, z reszta serwery tego sklepu tez nie maja, a i one musza wygenerowac zawartosc.

Chyba że wykona to równolegle, skrypt podzieli linki na partie i w tym samym czasie wykona do nich odwołanie.
kielich
Cytat
Chyba że wykona to równolegle, skrypt podzieli linki na partie i w tym samym czasie wykona do nich odwołanie.


Co masz na myśli questionmark.gif Możesz podać jakiś przykład ?
artuross
Cytat(!*! @ 2.04.2013, 15:19:36 ) *
Chyba że wykona to równolegle, skrypt podzieli linki na partie i w tym samym czasie wykona do nich odwołanie.


Mysle, ze to nie znacznie przyspieszy caly proces, bo:
1. on pobiera linki z jednej strony, dopiero przechodzi do drugiej, z niej pobiera, przechodzi do 3. strony, znow pobiera i dopiero z 4. strony pobiera cene.
2. serwer nadal musi obsluzyc kilkaset zapytan, w ktorych trzeba pobrac dane z bazy, itd., itp.

W najlepszym przypadku przyspieszy calosc o kilkanascie sekund (tak mysle, nie mowie ze tak jest NA PEWNO), a w najgorszym wykona mini-DoS i bedzie czekal jeszcze dluzej. Do tego dochodzi zabezpiecznie antyDDoS. Jesli serwer ma jakies oprogramowanie i faktycznie skrypt dzialalby powiedzmy 2x szybciej, to wykonanie 5160 zapytan w ciagu ~3 minut daje dosyc spora sume zapytan/sekunde z jednego adresu IP, a wtedy zamiast 5 minut poczeka sobie 15 albo i dluzej smile.gif
Nic tylko probowac biggrin.gif Ale nadal jestem zdania, ze nie spadnie ponizej 4 minut.

@up: http://www.php.net/manual/en/function.curl-multi-init.php
!*!
Nie mam pojęcia o działaniu równoległym w PHP (i czy jest samo w sobie jakieś narzedzie które to ulatwia), jak potrzebuję to na szybko piszę coś w bashu. Chodzi o to że jak masz skrypt A.php to w nim pobierasz linki od 0 do 300 i tak samo odpowiednio dla skryptu B.php, C.php itd. Później w konsoli wklepujesz
Cytat
php A.php & php B.php &
itd. w linux & na końcu odpala skrypt w tle, a php nazwapliku.php uruchamia nowy parser.

edycja
@artuross - tak, z tym tez trzeba się liczyć, ale kto mówi że trzeba pobierać wszytko razem i za jednym zamachem?
artuross
Cytat(!*! @ 2.04.2013, 15:34:02 ) *
@artuross - tak, z tym tez trzeba się liczyć, ale kto mówi że trzeba pobierać wszytko razem i za jednym zamachem?


No teoretycznie nikt nie mowie, ale problem w tym, ze kielich chcialby, aby to wszystko dzialo sie szybciej, wiec jezeli i tak bedzie musial czekac to chyba nie osiagnie zamierzonego efektu.
Wg mnie zostaw tak jak jest, a i tak powinienes sie cieszyc, ze nie maja SSL bo czekalbys 3x dluzej biggrin.gif Albo sprobuj pobierac tylko okreslone bity z calego zapytania, bo jak na razie bierzesz cala zawartosc strony: 'QAZWSXEDCRFVTGBYHNUJMIKOLP', a Ty potrzebujesz tylko 'DCRFVTGBYHNUJMIKOLP'
!*!
Będzie szybciej, bo skrypt nie będzie czekał aż wykona się w całości, tylko w tym samym czasie wykona się pobieranie poszczególnych grup linków. To tak jak z zakładkami w przeglądarce, jak otwierasz ich 5, to nie czekasz po kolei aż otworzy się 1 potem 2, 3, 4 i na końcu 5, tylko wczytują się od razu wszystkie naraz. Ograniczeniem jest tu jedynie łącze, zabezpieczenia serwera, ale przyspieszenie jest możliwe.
artuross
Tylko, ze gdy otwierasz karty w przegladarce otwierasz najczesciej rozne witryny, a nawet jezeli to jest ten sam serwer, to nie obsluguje on 300 wejsc w jednej chwili. A wydaje mi sie (tutaj nie jestem pewien), ze cURL nie obsluguje Keep-Alive, wiec i tak dochodza DNSy, cookies, itd. Z reszta, nie wazne, nie spierajmy sie kto ma racje (dobra, na 90% Ty masz racje wink.gif).

@kielich, wyprobuj kilka opcji, ale tak czy siak, skrypt nie wykona sie w 10 sekund smile.gif
kielich
A w jaki sposób moge pobrać odpowienie bity - długość ciągu źródła questionmark.gif
artuross
Mozesz dodac odpowiedni header, ktory poinstruuje serwer jakie bity ma zwracac. Tutaj musisz Googlowac.
!*!
Dlatego wspomniałem na początku o tych pętlach, zresztą cała klasa o dużo mówiącej nazwie "Klocki", leży, ale to jak i czy będzie działać, zależy od autora. EOT.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.