Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: phpDom getElementsByTagName() wywala mi błąd
Forum PHP.pl > Forum > PHP
tonyviroos
Witam
Tworzę scraper danych z użyciem phpDom i wszystko niby fajnie działa, wyciąga większość danych z html ale czasami wywala błąd:
  1. Fatal error: Call to a member function getElementsByTagName() on a non-object

Błąd niby znajduje się w linii 263:
  1. $rows = $description->item(0)->getElementsByTagName('tr');

Cała funkcja:
  1. public function getProductImages($url) {
  2. $this->loginToWeb();
  3. $domDocument = new DOMDocument();
  4. libxml_use_internal_errors(true);
  5. curl_setopt($this->curlHandler, CURLOPT_POST, 0);
  6. curl_setopt($this->curlHandler, CURLOPT_URL, $url);
  7. $content = curl_exec($this->curlHandler);
  8. $domDocument->loadHTML($content);
  9. libxml_clear_errors();
  10.  
  11. $domXPath = new DOMXpath($domDocument);
  12. $thumbnails = $domXPath->query('//ul[@class="thumbnails"]');
  13. $thumbsArray = array();
  14. if ($thumbnails->length > 0) {
  15.  
  16. for ($c = 0; $c < $thumbnails->item(0)->childNodes->length; $c++) {
  17. if (get_class($thumbnails->item(0)->childNodes->item($c)) == 'DOMElement') {
  18. if ($thumbnails->item(0)->childNodes->item($c)->childNodes->length > 0) {
  19. $thumbsArray[] = str_replace('small_thumb', 'krampd_rd', $thumbnails->item(0)->childNodes->item($c)->childNodes->item(1)->childNodes->item(1)->getAttribute('src'));
  20. }
  21. }
  22. }
  23.  
  24. $description = $domXPath->evaluate("/html/body//table[@id='attrsTable']");
  25. $rows = $description->item(0)->getElementsByTagName('tr');
  26. $html = '<table class="product_description">';
  27.  
  28. foreach ($rows as $row) {
  29. $html .= '<tr>';
  30. $cells = $row->getElementsByTagName('td');
  31.  
  32. foreach ($cells as $cell) {
  33. $html .= '<td>';
  34. $html .= $cell->nodeValue;
  35. $html .= '</td>';
  36. }
  37. $html .= '</tr>';
  38. }
  39. $html .= '</table>';
  40. return array('images' => $thumbsArray, 'description' => $html);
  41. }
  42. }


Dziwne jest to że błąd wyskakuje tylko czasami i nie mam pojęcia dlaczego.

Ma ktoś jakieś pomysły ?
nospor
Skoro wystepuje tylko czasami, to nie przyszlo ci do glowy, ze moze poprostu czasami zadne description, ktorego szukasz, nie istnieje?
tonyviroos
Przyszło mi do głowy ale właśnie problem w tym że istnieje a mimo to wywala się błąd.
nospor
wg. php $description->item(0) nie istnieje. Uwierz na slowo: skoro php mowi, ze cos nie istnieje, znaczy ze nie istnieje.
tonyviroos
Cytat(nospor @ 9.09.2015, 15:07:32 ) *
wg. php $description->item(0) nie istnieje. Uwierz na slowo: skoro php mowi, ze cos nie istnieje, znaczy ze nie istnieje.


Nie bardzo rozumiem co masz na myśli?

Chodzi o to że problem występuje niezależnie od tego czy descryption, którego szukam istnieje czy nie istnieje.
Nawet żeby było ciekawiej to dla produktu który nie ma opisu pobierane są wszystkie pozostałe dane, a wywala się na produkcie który posiada opis i to zupełnie losowo.
KsaR
Cytat(nospor @ 9.09.2015, 16:07:32 ) *
wg. php $description->item(0) nie istnieje. Uwierz na slowo: skoro php mowi, ze cos nie istnieje, znaczy ze nie istnieje.


  1. <?php
  2. // 5 elementów
  3. $array=array(
  4. 'key'=>'value',
  5. 0.1=>'a',
  6. 0.2=>'b',
  7. 0.3=>'c',
  8. 1=>'d'
  9. );
  10.  
  11. $count=count($array);
  12. echo 'Elementów: ',$count, '/5<br/>';
  13.  
  14. // jeśli mniej niż 5.
  15. if ($count<5)
  16. {
  17. foreach ($array as $k=>$v)
  18. {
  19. echo $k, ' (';
  20. var_dump($k);
  21. echo ')<br/>';
  22. }
  23. }

Cytat
Elementów: 3/5
key (string(3) "key" )
0 (int(0) )
1 (int(1) )

tongue.gif
nospor
@KsaR jak to sie ma do omawianego przykladu? To ze w niektorych momentach php sie zachowuje jak sie zachowuje, to uwierz, ale nie klamie gdy probujesz sie odwolac do obiektu a jego akurat nie ma. Wiec daruj sobie takie porownania.

Poza tym twoj "przyklad" jest o kant 4 liter, a to dlatego, ze nie czytasz dokumentacji
http://php.net/manual/en/language.types.array.php
Cytat
Floats are also cast to integers, which means that the fractional part will be truncated. E.g. the key 8.7 will actually be stored under 8.
Wiec wszystko przebieglo prawidlowo. Lektura podstaw sie klania.
KsaR
Cytat(nospor @ 9.09.2015, 16:44:28 ) *
@KsaR jak to sie ma do omawianego przykladu? To ze w niektorych momentach php sie zachowuje jak sie zachowuje, to uwierz, ale nie klamie gdy probujesz sie odwolac do obiektu a jego akurat nie ma. Wiec daruj sobie takie porownania.

No być może jakiś magiczny przypadek.. biggrin.gif
Może coś z wersją php ? Różnie bywa, nie ma oprogramowania bez błędów. Jednak mam zdanie jak ty że w tym wypadku wina programisty.
--
Hmm.
$this->curlHandler
Pokaż co masz w tej własności.
Całą definicję. Bo różnie bywa.
--
Edit. Ps. nospor, czytam. Dałem tylko przykład że "różnie bywa".
nospor
Cytat
Edit. Ps. nospor, czytam. Dałem tylko przykład że "różnie bywa".
Uzywasz php niezgodnie z instrukcją i dajesz to jako przyklad ze roznie bywa? No bez jaj.... php wyraznie mowi, ze 0.1 , 0.2 i 0.3 da tak czy siak 0 wiec tu wszytko w Twoim przykladzie jest ok a nie roznie bywa.

A w przykladzie co mamy, ewidetnie nie ma obiektu. Zamiast plakac na forum, niech autor da poprostu warunek na to czy jest obiekt czy nie. Skad mamy wiedziec co jest przyczyna tego, ze nagle tam nie ma obiektu, skoro dzialamy na strzepkach informacji. Tak, moze byc struktura html zepsuty, lub cos innnego - to ok, to roznie bywa. Ale nadal nie kumam jak sie ma do tego Twoj kod, gdzie to ty schrzaniles ewidetnie sprawe - to juz nie roznie bywa wink.gif
KsaR
Cytat(nospor @ 9.09.2015, 16:57:10 ) *
Uzywasz php niezgodnie z instrukcją i dajesz to jako przyklad ze roznie bywa? No bez jaj.... php wyraznie mowi, ze 0.1 , 0.2 i 0.3 da tak czy siak 0 wiec tu wszytko w Twoim przykladzie jest ok a nie roznie bywa.
(...)

No pierwszy przykład jaki przyszedł mi do głowy co może niektórych zaskoczyć itd.
jednak -
https://bugs.php.net/search.php?limit=30&am...mp;bug_type=All

Czasem zdarzają się błędy przypadki które nie są opisane w manualu, tzn są ale inaczej niż oczekiwany rezultat - czyli błędy (j.w.).
nospor
To bedziesz teraz w 90% przypadkow na forum wyskakiwal z takim postem bo w php zdarzają sie bledy? Bedzie na 99% zakladal, ze to wina php a nie bezmyslnosci programisty? Bo ja niestety z przypadkow na forum widze ze to zawsze na 100% wina programisty a nie php. Tutaj na 100% jes dokladnie to samo, czyli ze jak php mowi, ze nie ma obiektu, znaczy ze go nie ma. I nie doszukuj sie tu winy php, tylko albo zlego kodu albo zlej struktury html
KsaR
Cytat(nospor @ 9.09.2015, 17:03:50 ) *
To bedziesz teraz w 90% przypadkow na forum wyskakiwal z takim postem bo w php zdarzają sie bledy? Bedzie na 99% zakladal, ze to wina php a nie bezmyslnosci programisty? Bo ja niestety z przypadkow na forum widze ze to zawsze na 100% wina programisty a nie php. Tutaj na 100% jes dokladnie to samo, czyli ze jak php mowi, ze nie ma obiektu, znaczy ze go nie ma. I nie doszukuj sie tu winy php, tylko albo zlego kodu albo zlej struktury html

offtopic.gifaaevil.gif
Pisalem przecież:
Cytat(http://forum.php.pl/index.php?showtopic=244972&view=findpost&p=1170661)
Jednak mam zdanie jak ty że w tym wypadku wina programisty.


Dalsze posty byly tłumaczeniem się o co mniej-więcej chodziło mi
--
A problem pewnie jest z $this->curlHandler, tak jak pisalem.
Bo nie widac jak jest deklarowane, co przekazywane itd.
nospor
Cytat
A problem pewnie jest z $this->curlHandler, tak jak pisalem.
To nie problem z curlHandler, tylko z zawartoscią strony. A to dwie rozne rzeczy na tym etapie.
tonyviroos
OK daję cały plik importera z którym walczę.
Być może gdzieś zrobiłem głupi błąd bo różnie bywa ale wydaje mi się że wszystko jest OK od strony php.
  1. http://pastebin.com/rGaGnytx
KsaR
Cytat(tonyviroos @ 9.09.2015, 19:56:50 ) *
OK daję cały plik importera z którym walczę.
Być może gdzieś zrobiłem głupi błąd bo różnie bywa ale wydaje mi się że wszystko jest OK od strony php.
  1. http://pastebin.com/rGaGnytx

Cytat
  1. $loginURL = "https://www.strona_z_produktami.com/do/action/LogonAjaxCmd?";
  2. foreach ($postData as $k => $v) {
  3. $loginURL .= '&' . $k . '=' . $v;
  4. }


  1. $loginURL = 'https://www.strona_z_produktami.com/do/action/LogonAjaxCmd?';
  2. foreach ($postData as $k=>$v) {
  3. $loginURL.="{$k}={$v}&";
  4. }
  5. $loginURL=rtrim($loginURL,'&');

Choć to chyba nic nie zmieni hm.
--
Ja bym zrobił na twoim miejscu coś tego typu w tej metodzie co randomowe problemy:
  1. if ($this->isLoged)
  2. {
  3. // sprawdzanie DOM-u itd.
  4. }
  5. else
  6. {
  7. // jakiś błąd rzucić czy coś.
  8. return false;
  9. }
tonyviroos
Logowanie działa poprawnie tak samo jak pobieranie zdjęcia produktu, ceny i dostępności towaru, jedynie wywala się czasami na pobieraniu opisu.
nospor
I dlatego poraz kolejny mowie, ze to jest problem kodu HTML strony, z ktorej pobierasz kod. Ale poraz kolejny jestem ignorowany i zawziecie sluchasz postow ksara, ktore za duzo do tematu nie wnoszą.
tonyviroos
Cytat(nospor @ 9.09.2015, 20:12:59 ) *
I dlatego poraz kolejny mowie, ze to jest problem kodu HTML strony, z ktorej pobierasz kod. Ale poraz kolejny jestem ignorowany i zawziecie sluchasz postow ksara, ktore za duzo do tematu nie wnoszą.

Nie słucham tylko wyjaśniłem że to co proponuje nie ma nic wspólnego z opisywanem problemem.

Może w takim razie zaproponuj rozwiązanie tego problemu bo ja już wymiękam, teraz sprawdziłem 2 produkty i na jednym wywaliło błąd a na drugim przeszło bez problemu (oba produkty takie same, różnią się jedynie kolorem ale opis i wszystko inne jest takie samo, kod źródłowy również jest identyczny poza nazwą koloru przedmiotu)
nospor
Zeby ci pomoc, trzeba poznac kod zrodlowy, na ktorym sie twoj kod wykrzacza. Inaczej, jak juz mowilem wielokrotnie, to wrozenie z fusów.
tonyviroos
Kod strony z listą produktów
  1. http://pastebin.com/d0cAcvmB

Kod strony z opisem produktu
  1. http://pastebin.com/mkWAnrcM
nospor
http://pastebin.com/mkWAnrcM
I dlatego tu podanego wlanie produktu ci sie zawsze wywala?
tonyviroos
Cytat(nospor @ 9.09.2015, 20:48:12 ) *
http://pastebin.com/mkWAnrcM
I dlatego tu podanego wlanie produktu ci sie zawsze wywala?


Dla tego produktu jest OK, natomiast dla tego produktu już wywala błąd http://pastebin.com/yVZqSsGd
nospor
Daj w kodzie poprostu sprawdzanie, czy jesli get(0) nie jest obiektem, to nie pomin kod, ktory na tym operuje i po sprawie
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.